Javascript 将对象数组转换为哈希映射,由对象的属性值索引
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26264956/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert object array to hash map, indexed by an attribute value of the Object
提问by Naveen I
Use Case
用例
The use case is to convert an array of objects into a hash map based on string or function provided to evaluate and use as the key in the hash map and value as an object itself. A common case of using this is converting an array of objects into a hash map of objects.
用例是根据提供的字符串或函数将对象数组转换为哈希映射,以评估并用作哈希映射中的键和值作为对象本身。使用它的一个常见情况是将对象数组转换为对象的哈希映射。
Code
代码
The following is a small snippet in JavaScript to convert an array of objects to a hash map, indexed by the attribute value of object. You can provide a function to evaluate the key of hash map dynamically (run time). Hope this helps someone in future.
以下是 JavaScript 中的一个小片段,用于将对象数组转换为哈希映射,由 object 的属性值索引。您可以提供一个函数来动态评估哈希映射的键(运行时)。希望这对将来的人有所帮助。
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 hashmap
* @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;
};
You can find the gist here: Converts Array of Objects to HashMap.
您可以在此处找到要点:将对象数组转换为 HashMap。
回答by jmar777
This is fairly trivial to do with Array.prototype.reduce:
这与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' }
Note:Array.prototype.reduce()is IE9+, so if you need to support older browsers you will need to polyfill it.
注意:Array.prototype.reduce()是 IE9+,所以如果你需要支持旧浏览器,你需要对它进行 polyfill。
回答by mateuscb
Using ES6 Map(pretty well supported), you can try this:
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"}
回答by splintor
回答by shuk
Using ES6 spread + Object.assign:
使用 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}
回答by Pedro Lopes
回答by Fabiano Taioli
You can use the new Object.fromEntries()method.
您可以使用新Object.fromEntries()方法。
Example:
例子:
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}
回答by Jun711
You can use Array.prototype.reduce()and actual JavaScript Mapinstead just a JavaScript Object.
您可以使用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);
What is different between Map And Object?
Previously, before Map was implemented in JavaScript, Object has been used as a Map because of their similar structure.
Depending on your use case, if u need to need to have ordered keys, need to access the size of the map or have frequent addition and removal from the map, a Map is preferable.
Map 和 Object 有什么区别?
以前,在 JavaScript 实现 Map 之前,Object 因为它们的结构相似而被用作 Map。
根据您的用例,如果您需要有序的键、需要访问地图的大小或需要频繁地从地图中添加和删除,则最好使用地图。
Quote from MDN document:
Objects are similar to Maps in that both let you set keys to values, retrieve those values, delete keys, and detect whether something is stored at a key. Because of this (and because there were no built-in alternatives), Objects have been used as Maps historically; however, there are important differences that make using a Map preferable in certain cases:
引自MDN 文档:
对象与 Maps 类似,都可以让您将键设置为值、检索这些值、删除键,以及检测某个键是否存储了某些内容。正因为如此(并且因为没有内置的替代品),对象在历史上一直被用作地图;然而,在某些情况下,使用 Map 有一些重要的区别:
- The keys of an Object are Strings and Symbols, whereas they can be any value for a Map, including functions, objects, and any primitive.
- The keys in Map are ordered while keys added to object are not. Thus, when iterating over it, a Map object returns keys in order of insertion.
- You can get the size of a Map easily with the size property, while the number of properties in an Object must be determined manually.
- A Map is an iterable and can thus be directly iterated, whereas iterating over an Object requires obtaining its keys in some fashion and iterating over them.
- An Object has a prototype, so there are default keys in the map that could collide with your keys if you're not careful. As of ES5 this can be bypassed by using map = Object.create(null), but this is seldom done.
- A Map may perform better in scenarios involving frequent addition and removal of key pairs.
- 对象的键是字符串和符号,而它们可以是 Map 的任何值,包括函数、对象和任何原语。
- Map 中的键是有序的,而添加到对象的键则不是。因此,当迭代它时,一个 Map 对象按插入的顺序返回键。
- 您可以使用 size 属性轻松获取 Map 的大小,而 Object 中的属性数量必须手动确定。
- Map 是可迭代的,因此可以直接迭代,而迭代 Object 需要以某种方式获取其键并对其进行迭代。
- 一个对象有一个原型,所以如果你不小心,地图中有一些默认的键可能会与你的键发生冲突。从 ES5 开始,这可以通过使用 map = Object.create(null) 绕过,但很少这样做。
- Map在涉及频繁添加和删除密钥对的场景中可能表现得更好。
回答by baryo
es2015 version:
es2015版本:
const myMap = new Map(objArray.map(obj => [ obj.key, obj.val ]));
回答by Peter
This is what I'm doing in TypeScript I have a little utils library where I put things like this
这就是我在 TypeScript 中所做的我有一个小的 utils 库,我把这样的东西
export const arrayToHash = (array: any[], id: string = 'id') =>
array.reduce((obj, item) => (obj[item[id]] = item , obj), {})
usage:
用法:
const hash = arrayToHash([{id:1,data:'data'},{id:2,data:'data'}])
or if you have a identifier other than 'id'
或者如果您有除“id”以外的标识符
const hash = arrayToHash([{key:1,data:'data'},{key:2,data:'data'}], 'key')

