質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

1489閲覧

array.map()で配列を再構築する方法

SugiuraY

総合スコア318

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/10/08 11:19

編集2021/10/08 11:31

以下のような複数のオブジェクトを含む配列について、それぞれのオブジェジェクトの特定の条件を満たすものだけを抽出して、配列を再構築したいと考えております。

javascript

1var ary =[ 2{"name":"abe","age":20}, 3{"name":"suzuki","age":10}, 4{"name":"tanaka","age":20}, 5]

例えばage20だけを抽出して再構築したくて、forEachであれば

javascript

1re_ary = []; 2ary.forEach(function(obj){ 3obj.age ===20 ? re_ary.push(obj); 4})

といった具体の方法が想像できるのですが、破壊的メソッドであるArray.map()を使って、同じように条件を抽出して配列を再構築することはできるのでしょうか?

※末尾がなぜか表示上で文字化けするので、修正してみました。
本現象は運営に報告しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

特定の条件に合う要素だけを抽出して新しい配列を生成するので張ればArray.filter()が適当だと思います。
Array.prototype.filter() - JavaScript | MDN

なお、Array.map()は新しい配列を生成するので破壊的ではありません。
Array.prototype.map() - JavaScript | MDN

投稿2021/10/08 11:38

編集2021/10/08 11:40
surface_0

総合スコア497

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2021/10/08 11:57

ありがとうございます。ご指摘通りでした。 因みにfilter()の使い方が初めて分かりました。抽出自体はできるのですが、抽出かつプロパティを与えたい場合、filter()では実装不可能でforEachを素直に使うべきでしょうか。例えば re_ary = ary.filter(value=> return value['age']===20 //value.age > 30 ? value.categ = "年配":0; ) のように該当するオブジェクトに新たにプロパティを追加したいということを意図しております。
SugiuraY

2021/10/08 11:59

リファレンスを見る限り、文字通り条件に合う要素を抽出するだけのメソッドにも見えるのですが、もしこれも含めて使うべきがforEachであればその旨ご指摘いただければ幸いです。
maisumakun

2021/10/08 12:01

> 抽出かつプロパティを与えたい場合、filter()では実装不可能でforEachを素直に使うべきでしょうか。 filter().map()とすればいいのではないでしょうか?
surface_0

2021/10/08 12:14 編集

filter() は要素の変更には向きません。 抽出かつプロパティを追加するのならば、`filter().map()`とするのが良いと思います。 ちなみに直接連続して繋げなくても、このように↓一旦変数に入れて見た目を整えても問題ありません。 ``` const tmp_ary = ary.filter(value => value.age === 20); const re_ary = tmp_ary.map(value => { value.categ = value.age > 30 ? "年配" : "0"; return value; }); ```
SugiuraY

2021/10/08 12:26

お二方とも、コメントありがとうございます。 プロパティの追加ではないのですが、同じように要素を変化させようとして var res = ary.filter(obj=> obj.age===20).map(obj => {return obj.age = String(obj.age)}) とすると ['20', '20']というよくわからない結果を返してくるのですが、期待している結果は [ {"name":"abe","age":"20"}, {"name":"suzuki","age":"10"}, {"name":"tanaka","age":"20"}, ] なのですが、map()の使い方を誤っているのでしょうか? ※プロパティの追加も同じ要領であると想像しております。
maisumakun

2021/10/08 12:28

> map()の使い方を誤っているのでしょうか? はい、returnの値(String(obj.age))を入れた配列を作ります。
SugiuraY

2021/10/08 12:34

すみません、正直に申し上げてわからないです・・・ var res = ary.filter(obj=> obj.age===20).map(obj => //obj.push() のようなことでしょうか?
maisumakun

2021/10/08 12:38

> ※プロパティの追加も同じ要領であると想像しております。 mapの返り値は追加ではなくて、要素にしたいものを返してください。
SugiuraY

2021/10/08 12:41

はい、その考えに基づき var res = ary.filter(obj=> obj.age===20).map(obj => {return String(obj.age)}) console.log(res); で要素にしたいもの(String(obj.age))をreturnさせたのですが、、、うまくいかないという状況です。
maisumakun

2021/10/08 12:49

> 要素にしたいもの(String(obj.age))をreturnさせたのですが それだと、書いての通り文字列「だけ」を要素とした配列が得られます。ほしいオブジェクトをreturnさせてください。
SugiuraY

2021/10/08 12:52

ドキュメンとの該当箇所を見つけることができました。見落とし、大変失礼しました。 res = []; var res = ary.filter(obj=> obj.age===20).map(obj => { reObj = {} reObj.name = obj.name; reObj.age = String(obj.age); return reObj; }) で実装することができました。 一方で、オブジェクトを含む配列でこれをやるとキーが多くなるほど、上記のようにreturnすべき配列でそのまま残したいものを改めて格納する( reObj.name = obj.name;のような操作)は無駄が多いので、この操作に関してはあまりmap()が向いていないような気がしてきました。素人の発想であれば申し訳ございません。
maisumakun

2021/10/08 12:53

> キーが多くなるほど、上記のようにreturnすべき配列でそのまま残したいものを改めて格納する( reObj.name = obj.name;のような操作)は無駄が多い Object spread({...obj})やObject.assignで対応できます。
SugiuraY

2021/10/08 13:11

ありがとうございます。とても不格好ではあるのですが、理屈がわかったので、以下のようにString()も.categoryプロパティの追加もしつつ、代わらない要素はもとのまま埋めることができました。 res = []; var res = ary.filter(obj=> obj.age===20).map(obj => { addObj = {}; reObj = {}; obj.age > 30 ? addObj.category = "年配": addObj.category = "若輩者"; reObj = Object.assign(obj,addObj) chgObj = {} chgObj.age = String(obj.age); reObj = Object.assign(reObj,chgObj) return reObj; }) 本当に初心者故、こんなこともできるんだと少しだけ感動してしまいました。ドキュメントは申し少し見落とさないように根気よく眺める癖をつけようと思います。
guest

0

まずmapは破壊的メソッドではありません。
つまり ary.maparyを変化させません。(コールバック関数内で明示的に変化させればそれは別ですが)
mapは、与えられた関数を配列のすべての要素に対して呼び出し、その結果から新しい配列を生成するものです。
生成される新しい配列の要素の数は元の配列と同じになります。
要素の抽出には使えないのではないでしょうか。

投稿2021/10/08 11:35

itagagaki

総合スコア8402

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SugiuraY

2021/10/08 12:00

ご指摘ありがとうございます。完全に誤認しておりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問