1. ホーム
  2. javascript

[解決済み] 配列のすべてのオブジェクトにキーと値のペアを追加する

2023-02-09 01:50:06

質問

配列内のすべてのオブジェクトにkey:valueのパラメータを追加したいと思いました。

例えば

var arrOfObj = [{name: 'eve'},{name:'john'},{name:'jane'}];

さて、私はすべてのオブジェクトに新しいパラメータであるisActiveを追加したかったので、結果の配列は次のようになります。

例えば

    [{
    name: 'eve',
    isActive: true
}, {
    name: 'john',
    isActive: true
}, {
    name: 'jane',
    isActive: true
}]

私はいつでも配列の中をループしてキーと値のペアを挿入することができます。しかし、そうするためのより良い方法があるかどうか疑問に思っていました。

どのように解決するのですか?

この map() 関数はこの場合の最良の選択です


tl;dr - これを実行します。

const newArr = [
  {name: 'eve'},
  {name: 'john'},
  {name: 'jane'}
].map(v => ({...v, isActive: true}))

この map() 機能 は変更しません。 を変更せず、新しい配列を作成します。 これはまた、初期配列を変更しないための良い習慣です。


代替案 :

const initialArr = [
      {name: 'eve'},
      {name: 'john'},
      {name: 'jane'}
    ]

const newArr1 = initialArr.map(v => ({...v, isActive: true}))
const newArr2 = initialArr.map(v => Object.assign(v, {isActive: true}))

// Results of newArr1 and newArr2 are the same

キー・バリュー・ペアを追加する 条件付きで

const arr = [{value: 1}, {value: 1}, {value: 2}]   
const newArr1 = arr.map(v => ({...v, isActive: v.value > 1}))

条件がfalseの場合、新しいフィールドを全く追加したくない場合はどうすればよいですか?

const arr = [{value: 1}, {value: 1}, {value: 2}]   
const newArr = arr.map(v => {
  return v.value > 1 ? {...v, isActive: true} : v 
})

追加 WITH 初期配列の変更

const initialArr = [{a: 1}, {b: 2}]
initialArr.forEach(v => {v.isActive = true;});

これはおそらく最善のアイデアではありませんが、実際の生活の中では、時にはそれが唯一の方法であることがあります。


質問

  • スプレッド演算子を使うべき( ... ) を使うか、それとも Object.assign と、何が違うのでしょうか?

個人的にはspread演算子を使う方が好きです。最近のWebコミュニティではspread演算子が広く使われていると思うからです(特にreactの開発者は大好きです)。しかし、あなたは自分でその違いをチェックすることができます。 リンク (少し意見が古いが、それでも)

  • を使うことができますか? function キーワードの代わりに => ?

もちろん、できますよ。太い矢印( => ) 関数では少し異なる動作をします。 this とは少し違いますが、このケースではそれほど重要ではありません。しかし、ファットアロー関数はより短く、時にはコールバックとしてより良く機能します。したがって、ファットアロー関数の使用は、より近代的なアプローチです。

  • map関数の内部で実際に起こっていること。 .map(v => ({...v, isActive: true}) ?

Map関数は配列の要素に対して反復処理を行い、それぞれの要素に対してコールバック関数を適用します。コールバック関数は、新しい配列の要素となるものを返す必要があります。 私たちは .map() 関数に次のように伝えます:現在の値( v これはオブジェクトです)、すべてのキーと値のペアを v から全てのキーと値のペアを取り出して、新しいオブジェクト( {...v} ) の中に入れるだけでなく、プロパティ isActive を追加し、それを true に設定します ( {...v, isActive: true} ) に設定し、その結果を返します。もし、元のオブジェクトに isActive が含まれている場合は、上書きされます。 Object.assign も同じように動作します。

  • 一度に複数のフィールドを追加することはできますか?

はい、できます。

[{value: 1}, {value: 1}, {value: 2}].map(v => ({...v, isActive: true, howAreYou: 'good'}))

  • 内部でやってはいけないこと .map() メソッド

サイドエフェクトはしないほうがいい [リンク1 , リンク2] というのがありますが、どうやらできるようです。

また、注目すべきは map() は配列の各要素を繰り返し処理し、それぞれの要素に対して関数を適用します。そのため、内部で重い処理をすると遅くなる可能性があります。これは (ちょっとハチャメチャですが) 解決策 は、場合によってはより生産的かもしれません(ただし、一生に何度も適用する必要はないでしょう)。

  • map のコールバックを別の関数に抽出することはできますか?

もちろんできます。

const arr = [{value: 1}, {value: 1}, {value: 2}]   
const newArr = arr.map(addIsActive)

function addIsActive(v) {
    return {...v, isActive: true}
}

  • 古い良いforループの何が問題なのでしょうか?

何も問題ない for より冗長で安全性が低く、初期配列が変更される古いアプローチです。しかし、試してみることはできます。

const arr = [{a: 1}, {b: 2}]
for (let i = 0; i < arr.length; i++) {
 arr[i].isActive = true
}

  • また、私は何を学ぶべきですか?

以下の方法をよく学ぶとよいでしょう。 マップ() , filter() , reduce() , forEach() そして find() . これらのメソッドは、通常配列で行いたいことの80%を解決することができます。