JavaScriptでオブジェクト{}をキーと値のペアの配列[]に変換する方法


243

このようなオブジェクトを変換したい:

{"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

このようなキーと値のペアの配列に:

[[1,5],[2,7],[3,0],[4,0]...].

JavaScriptでオブジェクトをキーと値のペアの配列に変換するにはどうすればよいですか?

回答:


428

これを使用Object.keys()map()て行うことができます

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [Number(key), obj[key]];
});

console.log(result);


6
@blvckasvpキーとして数字を使用していますか?そうでない場合、キーを数値に変換しようとすると失敗し、NaN代わりに戻ります。文字列をキーとして使用する場合は、戻り値を[Number(key), obj[key]]toに変更する[key, obj[key]]Object.entries、回答で提案されている@Pilaを使用します
scottbot95

123

最善の方法は次のとおりです。

var obj ={"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10"‌​:0,"11":0,"12":0} 
Object.entries(obj);

entriesここに示すようにを呼び出す[key, value]と、質問者の要求に応じてペアが返されます。

または、Object.values(obj)値のみを返すを呼び出すこともできます。


6
開発者各位、数分前にリリースされたブラウザとのみ互換性のあるこれらの素晴らしい機能を採用する前に、ECMA互換性表を確認してください。
andreszs

8
@andreszs IEのサポートを中止してもかまわない場合(および2019年に、実際には使用しないことを望んでいる場合)、「使用できるかどうか」の表を参照してください。FF 47は2016年6月のもので、Chrome 54は同年10月のEdge 14 Augustのものです。正確には数分前ではありません。
Kyll

参考:Object.entriesは[key、value]を返しますが、キーは文字列になり、値は異なります。
SHAHBAZ

61

Object.entries()要素がで[key, value]直接見つかった列挙可能なプロパティのペアに対応する配列である配列を返しますobject。プロパティの順序は、オブジェクトのプロパティ値を手動でループすることによって与えられるものと同じです。

- https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries#Description

このObject.entries関数は、キーが数字ではなく文字列であることを除いて、ほぼ正確に出力を返します。

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

console.log(Object.entries(obj));

キーを数値にする必要がある場合は、各ペアのキーを強制的に変換された数値に置き換えるコールバック関数を使用して、結果を新しい配列にマッピングできます。

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
    const entries = Object.entries(input);
    return entries.map(entry => Object.assign(entry, { 0: +entry[0] }));
}

console.log(toNumericPairs(obj));

Object.assign上記の例では、矢印関数とマップコールバックに使用しているので、Object.assign割り当てられているオブジェクトを返すという事実を利用して1つの命令に保持できます。1つの命令の矢印関数の戻り値は、命令の結果です。

これは次と同等です。

entry => {
    entry[0] = +entry[0];
    return entry;
}

コメントで@TravisClarkeが言及したように、マップ関数は次のように短縮できます。

entry => [ +entry[0], entry[1] ]

ただし、既存の配列を変更する代わりに、キーと値のペアごとに新しい配列が作成されるため、作成されるキーと値のペアの配列の数が2倍になります。元のエントリ配列は引き続きアクセス可能ですが、それとそのエントリはガベージコレクションされません。

ここで、インプレースメソッドを使用しても、キーと値のペアを保持する2つの配列(入力配列と出力配列)が引き続き使用されますが、配列の総数は1つだけ変化します。入力配列と出力配列は実際には配列で埋められていませんが、配列への参照とそれらの参照がメモリ内で取るに足らない量のスペースしか占めていません。

  • 各キーと値のペアをインプレースで変更すると、メモリの増加量はごくわずかになりますが、さらに数文字を入力する必要があります。
  • キーと値のペアごとに新しい配列を作成すると、必要なメモリの量が2倍になりますが、入力する文字が少し少なくなります。

新しい配列にマッピングする代わりに、entries配列をインプレースで変更することで、さらに一歩進んで成長を完全になくすことができます。

const obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

const toNumericPairs = input => {
  const entries = Object.entries(obj);
  entries.forEach(entry => entry[0] = +entry[0]);
  return entries;
}

console.log(toNumericPairs(obj));


1
機能的なアプローチが好きです。より短い代替案として:Object.entries(obj).map(e => [+e[0], e[1]]);
Travis Clarke

20

ES6が標準となっている2018年に、これらの回答のいくつかを要約します。

オブジェクトから始めます:

let const={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
  • 配列の値を盲目的に取得するだけで、キーは気にしないでください:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.values(obj));
//[9,8,7,6,5,4,3,2,1,0,5]

  • 配列のペアを取得するだけです:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj));
//[["1",9],["2",8],["3",7],["4",6],["5",5],["6",4],["7",3],["8",2],["9",1],["10",0],["12",5]]

  • 前と同じですが、各ペアに数字キーがあります:

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).map(([k,v])=>[+k,v]));
//[[1,9],[2,8],[3,7],[4,6],[5,5],[6,4],[7,3],[8,2],[9,1],[10,0],[12,5]]

  • オブジェクトプロパティを新しい配列のキーとして使用する(スパース配列を作成できます):

const obj={"1":9,"2":8,"3":7,"4":6,"5":5,"6":4,"7":3,"8":2,"9":1,"10":0,"12":5};
console.log(Object.entries(obj).reduce((ini,[k,v])=>(ini[k]=v,ini),[]));
//[undefined,9,8,7,6,5,4,3,2,1,0,undefined,5]

この最後の方法では、キーの値に応じて配列の順序を再編成することもできます。これが望ましい動作になる場合があります(そうでない場合もあります)。しかし、現在の利点は、値が正しい配列スロットにインデックス付けされていることです。これは、値を検索するために不可欠であり、簡単です。

  • 配列の代わりにマップ

最後に(元の質問の一部ではありませんが、完全を期すため)、キーまたは値を使用して簡単に検索する必要があるが、スパース配列、重複なし、および数値キーに変換する必要のない並べ替えが不要な場合(非常に複雑なキーにアクセスすることもできます)、配列(またはオブジェクト)は必要ありません。お勧めしますMap代わりにます:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map

let r=new Map(Object.entries(obj));
r.get("4"); //6
r.has(8); //true

2
4番目以降の箇条書きは質問とはまったく関係ありません。残りの回答は、ここで上位3つの回答を要約したものです。この回答は、まだここになかった、または完全に無関係ではない議論には何ももたらしません。

はい、最初の行の状態として、これは回答の要約です。次に、フルブロー機能の代わりに最新のES6テクニックを使用するように回答を更新します。4番目の回答は、連想配列をサポートする言語(PHPなど)からJSON配列を移動する場合に役立ちます。
CarlosH。

ここで提供されるすべてのメソッドは、上位3つの回答のうち2つですでにプレーンな形で提供されています。これらは関数ではないので、何をしているのかわかりません。第4回までは、私が言ったように、尋ねられた質問とはまったく無関係です。これは別の質問に関連している可能性がありますが、これは問題ではありません。いずれにせよ、JSONは、PHP、JavaScript、Haskellのいずれを使用して作成された場合でもJSONです。

18

Object.entriesあなたのためにうまくいかない場合のさらに別の解決策。

const obj = {
      '1': 29,
      '2': 42
    };
const arr = Array.from(Object.keys(obj), k=>[`${k}`, obj[k]]);
console.log(arr);


1
これでうまくいきました。JSONをインポートするとインデックスが追加され、Angulars ngForループを使用できなくなるという問題が発生しました。これにより、構造を維持しながらインデックスが削除されました。
RAC

「インデックス」の代わりに「インデックス」を使用するための@RAC +1。古びた、古風な(すなわち、恣意的で無意味に逸脱した)イギリスの伝統!
Venryx

12

Ecmascript 6では

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0};

var res = Object.entries(obj);

console.log(res);

バイオリン


なぜこれが反対票が投じられたのかわからない、完璧に機能した
sMyles

1
私は反対票を投じませんでしたが、その.map((value)=>(value))部分は無意味であることに注意してくださいObject.entries(obj)。呼び出しから取得した配列とまったく同じエントリー配列を返すだけです。
Venryx

8

使用Object.keysArray#map方法。

var obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};
// get all object property names
var res = Object.keys(obj)
  // iterate over them and generate the array
  .map(function(k) {
    // generate the array element 
    return [+k, obj[k]];
  });

console.log(res);


7

Object.entriesObjectの各要素をkey & valueフォーマットで取得するために使用してから、次のmapようにそれらを介して:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}

var res = Object.entries(obj).map(([k, v]) => ([Number(k), v]));

console.log(res);

しかし、あなたはキーがになることを確信している場合、プログレッシブ順序を使用できObject.valuesそしてArray#map、このような何かを:

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}; 

                        // idx is the index, you can use any logic to increment it (starts from 0)
let result = Object.values(obj).map((e, idx) => ([++idx, e]));

console.log(result);



5

lodashでは、上記の回答に加えて、出力配列にキーを含めることもできます。

出力配列にオブジェクトキーがない場合

ために:

const array = _.values(obj);

objが次の場合:

{ art”: { id: 1,  title: aaaa }, fiction”: { id: 22,  title: 7777”} }

配列は次のようになります:

[ { id: 1, title: aaaa }, { id: 22, title: 7777 } ]

出力配列のオブジェクトキーを使用

代わりに書く場合( 'genre'は選択した文字列です):

const array= _.map(obj, (val, id) => {
    return { ...val, genre: key };
  });

あなたは得るでしょう:

[ 
  { id: 1, title: aaaa , genre: art”}, 
  { id: 22, title: 7777”, genre: fiction }
]

4

私はこの最も簡単なソリューションを使用することをお勧めします Object.entries()

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result =Object.entries(obj)

console.log(result);


1

を使用できますObject.values([])。まだ使用していない場合は、このポリフィルが必要になることがあります。

const objectToValuesPolyfill = (object) => {
  return Object.keys(object).map(key => object[key]);
};
Object.values = Object.values || objectToValuesPolyfill;

https://stackoverflow.com/a/54822153/846348

その後、あなたはただ行うことができます:

var object = {1: 'hello', 2: 'world'};
var array = Object.values(object);

jsの配列は数値キーしか使用できないので、オブジェクトで何か他のものを使用した場合、それらは `0,1,2 ... x``になることに注意してください。

たとえば、一意のキーがある場合は、重複を削除すると便利です。

var obj = {};
object[uniqueKey] = '...';

0

使用中のため

var obj = { "10":5, "2":7, "3":0, "4":0, "5":0, "6":0, "7":0,
            "8":0, "9":0, "10":0, "11":0, "12":0 };

var objectToArray = function(obj) {
    var _arr = [];

    for (var key in obj) {
        _arr.push([key, obj[key]]);
    }
    return _arr;
}

console.log(objectToArray(obj));

0

オブジェクトを配列に再帰的に変換

function is_object(mixed_var) {
    if (mixed_var instanceof Array) {
        return false;
    } else {
        return (mixed_var !== null) && (typeof( mixed_var ) == 'object');
    }
}


function objectToArray(obj) {
    var array = [], tempObject;
    for (var key in obj) {

        tempObject = obj[key];

        if (is_object(obj[key])) {
            tempObject = objectToArray(obj[key]);
        }
        array[key] = tempObject;
    }
    return array;
}

0

以下のように、NumberをKeyの文字列型に変更できます。

var obj = {"1":5,"2":7,"3":0,"4":0,"5":0,"6":0,"7":0,"8":0,"9":0,"10":0,"11":0,"12":0}
var result = Object.keys(obj).map(function(key) {
  return [String(key), obj[key]];
});
    
console.log(result);


0

これは私の解決策ですが、私は同じ問題を抱えており、この解決策は私にとってうまくいくようです。

yourObj = [].concat(yourObj);

0

これは私のシンプルなベアボーン実装です:

let obj = {
  "1": 5,
  "2": 7,
  "3": 0,
  "4": 0,
  "5": 0,
  "6": 0,
  "7": 0,
  "8": 0,
  "9": 0,
  "10": 0,
  "11": 0,
  "12": 0
};    

const objectToArray = obj => {
      let sol = [];
      for (key in obj) {
        sol.push([key, obj[key]]);
      }
      return sol;
    };

objectToArray(obj)

0

シンプルなソリューション

`

var result = Object.keys(records).map(function (value) {
         return { [value]: records[value] };
});
console.log(result);


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