web-dev-qa-db-ja.com

オブジェクトの属性値でインデックス付けされたオブジェクト配列をハッシュマップに変換する

ユースケース

ユースケースは、ハッシュマップ内のキーとして評価および使用し、オブジェクト自体としての値として使用するために提供される文字列または関数に基づいて、オブジェクトの配列をハッシュマップに変換することです。これを使用する一般的なケースは、オブジェクトの配列をオブジェクトのハッシュマップに変換することです。

コード

次に示すのは、オブジェクトの配列をハッシュマップに変換し、オブジェクトの属性値でインデックスを付ける、JavaScriptの小さなコードです。ハッシュマップのキーを動的に(ランタイムに)評価する機能を提供できます。これが将来誰かに役立つことを願っています。

function isFunction(func){
    return Object.prototype.toString.call(func) === '[object Function]';
}

/**
 * This function converts an array to hash map
 * @param {String | function} key describes the key to be evaluated in each object to use as key for hasmap
 * @returns Object
 * @Example 
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id")
 *      Returns :- Object {123: Object, 345: Object}
 *
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1})
 *      Returns :- Object {124: Object, 346: Object}
 */
Array.prototype.toHashMap = function(key){
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];};
    this.forEach(function (obj){
        _hashMap[getKey(obj)] = obj;
    });
    return _hashMap;
};

あなたはここで要旨を見つけることができます: https://Gist.github.com/naveen- ithappu/c7cd5026f6002131c1fa

177
Naveen I

これは Array.prototype.reduce とするのはかなり簡単です。

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = arr.reduce(function(map, obj) {
    map[obj.key] = obj.val;
    return map;
}, {});

console.log(result);
// { foo: 'bar', hello: 'world' }

注: Array.prototype.reduce()はIE9 +なので、古いブラウザをサポートする必要がある場合はポリフィルする必要があります。

311
jmar777

ES6 Mapかなりよくサポートされた )を使って、これを試すことができます。

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = new Map(arr.map(i => [i.key, i.val]));

// When using TypeScript, need to specify type:
// var result = arr.map((i): [string, string] => [i.key, i.val])

// Unfortunately maps don't stringify well.  This is the contents in array form.
console.log("Result is: " + JSON.stringify([...result])); 
// Map {"foo" => "bar", "hello" => "world"}
205
mateuscb

lodash では、 keyBy を使用してこれを実行できます。

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = _.keyBy(arr, o => o.key);

console.log(result);
// Object {foo: Object, hello: Object}
30
splintor

スプレッド演算子を使用する:

const result = arr.reduce(
    (accumulator, target) => ({ ...accumulator, [target.key]: target.val }),
    {});

jsFiddle のコードスニペットのデモ。

19
Pedro Lopes

Array.prototype.reduce() と実際のJavaScript Map の代わりにJavaScript Object を使うことができます。

let keyValueObjArray = [
  { key: 'key1', val: 'val1' },
  { key: 'key2', val: 'val2' },
  { key: 'key3', val: 'val3' }
];

let keyValueMap = keyValueObjArray.reduce((mapAccumulator, obj) => {
  // either one of the following syntax works
  // mapAccumulator[obj.key] = obj.val;
  mapAccumulator.set(obj.key, obj.val);

  return mapAccumulator;
}, new Map());

console.log(keyValueMap);
console.log(keyValueMap.size);

マップとオブジェクトの違いは何ですか?
以前は、MapがJavaScriptで実装される前は、Objectは構造が似ているためMapとして使用されていました。
ユースケースに応じて、キーを注文する必要がある場合、マップのサイズにアクセスする必要がある場合、またはマップの追加と削除を頻繁に行う必要がある場合は、Mapが適しています。

MDN文書からの引用
オブジェクトは、キーに値を設定し、それらの値を取得し、キーを削除し、何かがキーに格納されているかどうかを検出できるという点でMapsに似ています。このため(そして組み込みの代替手段がないため)、オブジェクトは歴史的にマップとして使用されてきました。ただし、特定の場合にMapを使用することを推奨する重要な違いがいくつかあります。

  • オブジェクトのキーは文字列とシンボルですが、関数、オブジェクト、プリミティブなど、マップの任意の値にすることができます。
  • Mapのキーは順序付けされていますが、objectに追加されたキーは順序付けられていません。したがって、それを反復処理すると、Mapオブジェクトは挿入順にキーを返します。
  • オブジェクトのプロパティ数は手動で決定する必要がありますが、sizeプロパティを使用してMapのサイズを簡単に取得できます。
  • Mapは反復可能なので直接反復することができますが、Objectを反復するには何らかの方法でキーを取得し、それらを反復する必要があります。
  • Objectはプロトタイプを持っているので、注意しないとマップにデフォルトのキーが衝突する可能性があります。 ES5では、これはmap = Object.create(null)を使用してバイパスできますが、これはほとんど行われていません。
  • キーペアの頻繁な追加と削除を含むシナリオでは、マップのパフォーマンスが向上することがあります。
10
Jun711

es2015バージョン:

const myMap = new Map(objArray.map(obj => [ obj.key, obj.val ]));
7
baryo

ES6スプレッド+ Object.assignを使用する:

array = [{key: 'a', value: 'b', redundant: 'aaa'}, {key: 'x', value: 'y', redundant: 'zzz'}]

const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));

console.log(hash) // {a: b, x: y}
6
Omer Shukar

これは私がTypeScriptでやっていることです私はこのようなものを置く私は小さなutilsライブラリを持っている

export const arrayToHash = (array: any[], id: string = 'id') => 
         array.reduce((obj, item) =>  (obj[item[id]] = item , obj), {})

使用法:

const hash = arrayToHash([{id:1,data:'data'},{id:2,data:'data'}])

または 'id'以外の識別子がある場合

const hash = arrayToHash([{key:1,data:'data'},{key:2,data:'data'}], 'key')
4
Peter

簡単なJavascriptを使う

var createMapFromList = function(objectList, property) {
    var objMap = {};
    objectList.forEach(function(obj) {
      objMap[obj[property]] = obj;
    });
    return objMap;
  };
// objectList - the array  ;  property - property as the key
2
Partha Roy

他のポスターで説明されているようにこれを行うにはもっと良い方法があります。しかし、私が純粋なJSと昔ながらのやり方に固執したいのであれば、それはここにあります:

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' },
    { key: 'hello', val: 'universe' }
];

var map = {};
for (var i = 0; i < arr.length; i++) {
    var key = arr[i].key;
    var value = arr[i].val;

    if (key in map) {
        map[key].Push(value);
    } else {
        map[key] = [value];
    }
}

console.log(map);
1
rhel.user

新しいES6に変換したい場合は、 Map とします。

var kvArray = [['key1', 'value1'], ['key2', 'value2']];
var myMap = new Map(kvArray);

なぜあなたはこのタイプの地図を使うべきですか?まあそれはあなた次第です。 this を見てください。

1
Tiago Bértolo

やってみる

let toHashMap = (a,f) => a.reduce((a,c)=> (a[f(c)]=c,a),{});
let arr=[
  {id:123, name:'naveen'}, 
  {id:345, name:"kumar"}
];

let fkey = o => o.id; // function changing object to string (key)

let toHashMap = (a,f) => a.reduce((a,c)=> (a[f(c)]=c,a),{});

console.log( toHashMap(arr,fkey) );

// Adding to prototype is NOT recommented:
//
// Array.prototype.toHashMap = function(f) { return toHashMap(this,f) };
// console.log( arr.toHashMap(fkey) );
1

新しい Object.fromEntries() メソッドを使用できます

const array = [
   {key: 'a', value: 'b', redundant: 'aaa'},
   {key: 'x', value: 'y', redundant: 'zzz'}
]

const hash = Object.fromEntries(
   array.map(e => [e.key, e.value])
)

console.log(hash) // {a: b, x: y}
1
Fabiano Taioli

reduceの使い方を少し改善しました。

var arr = [
    { key: 'foo', val: 'bar' },
    { key: 'hello', val: 'world' }
];

var result = arr.reduce((map, obj) => ({
    ...map,
    [obj.key] = obj.val
}), {});

console.log(result);
// { foo: 'bar', hello: 'world' }
1
Mor Shemesh

以下は、オブジェクトの属性値でインデックス付けされた、オブジェクトの配列をハッシュマップに変換するためにJavaScriptで作成した小さなスニペットです。ハッシュマップのキーを動的に(ランタイムに)評価する機能を提供できます。

function isFunction(func){
    return Object.prototype.toString.call(func) === '[object Function]';
}

/**
 * This function converts an array to hash map
 * @param {String | function} key describes the key to be evaluated in each object to use as key for hasmap
 * @returns Object
 * @Example 
 *      [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap("id")
        Returns :- Object {123: Object, 345: Object}

        [{id:123, name:'naveen'}, {id:345, name:"kumar"}].toHashMap(function(obj){return obj.id+1})
        Returns :- Object {124: Object, 346: Object}
 */
Array.prototype.toHashMap = function(key){
    var _hashMap = {}, getKey = isFunction(key)?key: function(_obj){return _obj[key];};
    this.forEach(function (obj){
        _hashMap[getKey(obj)] = obj;
    });
    return _hashMap;
};

あなたはここで要旨を見つけることができます: https://Gist.github.com/naveen- ithappu/c7cd5026f6002131c1fa

0
Naveen I