配列からオブジェクトを作成する


83

配列のリストからオブジェクトを作成したい。私は次のように見えると思われる動的な配列を持っています:

var dynamicArray = ["2007", "2008", "2009", "2010"];

そして、いくつかのjavascript es6を使用して、次のようなオブジェクトを作成します。

const obj = {
    2007: {
        x: width / 5,
        y: height / 2
    },
    2008: {
        x: (2 / 5) * width,
        y: height / 2
    },
    2009: {
        x: (3 / 5) * width,
        y: height / 2
    },
    2010: {
        x: (4 / 5) * width,
        y: height / 2
    }
}

内部オブジェクトについて心配する必要はありませんが、次のような構造を作成したかっただけです。

 obj = {
      2007: ...,
      2008: ...,
      ...
    }

助けてください、ありがとう。


2
はい。何を試しましたか?どこに行き詰まっていますか?どんな研究をしましたか?たとえば、これを見たことがありますか?
TJ Crowder 2017年

回答:


202

単に

 const obj = {};

 for (const key of yourArray) {
      obj[key] = whatever;
 }

または「機能的な」スタイルを好む場合:

 const obj = yourArray.reduce((o, key) => Object.assign(o, {[key]: whatever}), {});

最新のオブジェクト拡散演算子の使用:

const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})

例:

[
  { id: 10, color: "red" },
  { id: 20, color: "blue" },
  { id: 30, color: "green" }
].reduce((acc, cur) => ({ ...acc, [cur.color]: cur.id }), {})

出力:

{red: 10, blue: 20, green: 30}

仕組みは次のとおりです。

reduceは空のオブジェクト({}最後は空)で初期化されるため、最初の反復変数はacc = {} cur = { id: 10, color: "red" }です。関数はオブジェクトを返します-これが関数本体が括弧で囲まれている理由=> ({ ... })です。Spread演算子は最初の反復では何もしないためred: 10、最初の項目として設定されます。

2回目の反復では、変数はacc = { red: 10 } cur = { id: 20, color: "blue" }です。ここで、spread演算子が展開さ accれ、関数はを返します{ red: 10, blue: 20 }

3回目の反復なacc = { red: 10, blue: 20 } cur = { id: 30, color: "green" }ので、accがオブジェクト内に広がると、関数は最終値を返します。


1
ありがとう!必要に応じて動作しました。私はarray.reduce機能について知りませんでした。
Hussain Dehgamwala 2017年

機能的なスタイルを好む場合、そして私がそうする場合は、を使用する必要がありますconst。実際には関係なく使用する必要があります。また、ES Nextのレスト/スプレッド構文にアクセスできる場合(たとえば、TypeScriptまたはBabelを介して)const obj = yourArray.reduce((o, key) => ({ ...o, [key]: whatever}), {})、シードの変更を記述し、回避することもできます:p
Aluan Haddad 2017

1
@AluanHaddad:良い提案、投稿をCWに変換、自由に編集してください。
georg 2017

({... o、[key]:candidateDoc [key]})..ここで、candidateDocはいくつかのpojoです。CandidateDocで定義されている値のみを取得したい。しかし、私は括弧と混同されており、「return」またはifステートメントが機能するようには見えません。ドキュメントを読むことを恐れずに、正しい方向に私を向けていただけませんか。
terary

1
@cameck:ありがとう、投稿はCWです。自由に編集してください。
ゲオルク

33

Object.fromEntriesECMAScript 2019の新しい機能により、配列の値を次のようなオブジェクトのキーに変換するのがさらに簡単になります。

const dynamicArray = ["2007", "2008", "2009", "2010"];
const obj = Object.fromEntries(
  dynamicArray.map(year => [year, {
    something: "based",
    on: year
  }])
)

console.log(obj)


17

配列のes6reduce関数を使用したjsでは、このようにします

let x = [1,2,3]
let y = x.reduce((acc, elem) => {
  acc[elem] = elem // or what ever object you want inside
  return acc
}, {})
console.log(y) // {1:1, 2:2, 3:3}

3
さらに短い:[1, 2, 3].reduce((x, y)=>(x[y] = 1, x), {})
exebook

4
var keys = ['key1', 'key2', 'key3']

var object = Object.assign({}, ...Object.entries({...keys}).map(([a,b]) => ({ [b]: 'someValue' })))
console.log(object)

これにより、

{ key1: 'someValue', key2: 'someValue', key3: 'someValue' }

0

実際にObject.assign()は、spread演算子を直接使用できることがわかりました。reduceormap関数でこれ以上複雑にする必要はありません。

単に行うだけでObject.assign(...yourArray, {})、希望する結果が得られます。代わりに、オブジェクトの配列を別のオブジェクトにマージする場合は、呼び出すこともできますObject.assign(...yourArray, yourObject)。これも問題なく機能します。

この同じ方法を使用して、配列の1つにオブジェクトが含まれておらず、プリミティブ値のみが含まれている場合でも、2つの配列を1つのオブジェクトにマージすることもできます。ただし、これを行う場合は、少なくとも1つの配列がオブジェクトのみを保持していることを確認する必要があります。プリミティブはデフォルトでそのインデックスにとして設定されるkeyため、重複するキーがあるとエラーが発生します。

ただし、OPの目的では、空のオブジェクトとマージするため、このようなエラーのリスクはありません。これが最も安全な方法です。

const arr = [
  { a: 0 },
  { c: 1 },
  { e: 2 },
];

const obj = Object.assign(...arr, {});

console.log(obj)

// Results to:
// Object { a: 0, c: 1, e: 2 }

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.