简体   繁体   English

从对象数组创建一个新对象,并按特定的匹配键/值分组

[英]Creating a new object from array of objects and grouping by specific matching key/value

Example of the object data I am dealing with 我正在处理的对象数据的示例

var myData = [{
  "name": "John",
  "age": 30,
  "interest": "Baseball"
},
{
  "name": "Bob",
  "age": 21,
  "interest": "Baseball"
},
{
  "name" : "Sally",
  "age" : 29,
  "interest": "Tennis"
}]

I am trying to figure out the easiest way to group them by interests. 我正在尝试找出按兴趣分组的最简单方法。 I am open to using lodash or underscore, but I cannot get the final result to look like this.... 我愿意使用lodash或下划线,但是我无法获得最终的结果。

I want this to be the output: 我希望这是输出:

[{ "Baseball" : [{
                  "name": "John",
                  "age" : 30
                 },
                 {
                  "name" : "Bob",
                  "age" : 21
                 }]
 },
 { "Tennis" : [{
                 "name" : "Sally",
                 "age" : 21
               }]
 }];

Basically, each interest becomes a new object key containing all of the matched values within arrays. 基本上,每个兴趣都变成一个新的对象键,其中包含数组中所有匹配的值。

I am having trouble constructing this output. 我在构造此输出时遇到了麻烦。 Any assistance would be greatly appreciated. 任何帮助将不胜感激。 I prefer to use lodash/underscore to keep things very easy. 我更喜欢使用lodash /下划线使事情变得很容易。

Thank you! 谢谢!

A group-by operation can be done by matching values in a dictionary (hashtable). 分组操作可以通过匹配字典(哈希表)中的值来完成。 In JavaScript all objects are dictionaries with property-names as the keys, for values we use arrays. 在JavaScript中,所有对象都是带有属性名作为键的字典,对于值,我们使用数组。

For example (press the "Run code snippet" button below to see the results): 例如(按下面的“运行代码段”按钮查看结果):

 function groupBy( input, propertyName ) { var output = {}; for(var i = 0; i < input.length; i++) { var groupByValue = input[i][propertyName]; if( !(groupByValue in output) ) { output[ groupByValue ] = []; } var dolly = cloneObjectButIgnoreProperty( input[i], propertyName ); output[ groupByValue ].push( dolly ); } return output; } function cloneObjectButIgnoreProperty( value, ignorePropertyName ) { var dolly = {}; var propertyNames = Object.keys( value ); for( var i = 0; i < propertyNames .length; i++ ) { var propertyName = propertyNames[i]; if( propertyName == ignorePropertyName ) continue; dolly[propertyName ] = value[propertyName ]; } return dolly; } var myData = [ { "name": "John", "age": 30, "interest": "Baseball" }, { "name": "Bob", "age": 21, "interest": "Baseball" }, { "name" : "Sally", "age" : 29, "interest": "Tennis" } ]; var groupedByInterest = groupBy( myData, 'interest' ); console.log( "By interest:" ); console.log( groupedByInterest ); var groupedByName = groupBy( myData, 'name' ); console.log( "By name:" ); console.log( groupedByName ); var groupedByAge = groupBy( myData, 'age' ); console.log( "By age:" ); console.log( groupedByAge ); 

You could use Array.reduce for this: 您可以为此使用Array.reduce

 var myData = [ { "name": "John", "age": 30, "interest": "Baseball" }, { "name": "Bob", "age": 21, "interest": "Baseball" }, { "name" : "Sally", "age" : 29, "interest": "Tennis" }]; var result = myData.reduce(function(entities, obj) { entities[obj.interest] = (entities[obj.interest] || []).concat({ name: obj.name, age: obj.age }); return entities; }, {}); console.log(result); 

A little bit more general approach: 更一般的方法:

 function groupBy(data, key, tFunc) { mapFunc = (typeof tFunc === "function")? tFunc: function(o) { return o }; return (Array.isArray(data)?data:[]).reduce(function(entities, o) { if(o[key]) { entities[o[key]] = (entities[o[key]] || []).concat(tFunc(o)); } return entities; }, {}); } // test code var myData = [ { "name": "John", "age": 30, "interest": "Baseball" }, { "name": "Bob", "age": 21, "interest": "Baseball" }, { "name" : "Sally", "age" : 29, "interest": "Tennis" }]; var result = groupBy(myData, "interest", function(o) { return { name: o.name, age: o.age}}); console.log(result); var result2 = groupBy(myData, "age", function(o) { return o.name}); console.log(result2); 

The solution using Array.prototype.reduce() function: 使用Array.prototype.reduce()函数的解决方案:

 var myData = [{ "name": "John", "age": 30, "interest": "Baseball" }, { "name": "Bob", "age": 21, "interest": "Baseball" }, { "name" : "Sally", "age" : 29, "interest": "Tennis" }], result = myData.reduce(function (r, o) { r[o.interest] = r[o.interest] || []; r[o.interest].push({name: o.name, age: o.age}); return r; }, {}); console.log(result); 

 var myData = [{name:"John",age:30,interest:"Baseball"},{name:"Bob",age:21,interest:"Baseball"},{name:"Sally",age:29,interest:"Tennis"}], result = [], interests = [...new Set(myData.map(v => v.interest))]; interests.forEach(v => result.push({ [v] : [] })); myData.forEach((v,i) => result.forEach((c,i) => Object.keys(c)[0] == v.interest ? result[i][v.interest].push({name: v.name, age: v.age}) : c)) console.log(result); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从没有特定键值的 Object 创建对象数组 - Creating An Array of Objects From An Object Without Specific Key Values 从 object 中提取键值到具有特定字段的对象数组中 - Extracting key value from object into array of objects with specific fields 如何从具有特定键值的对象数组中获取 object? - How to get an object from an array of objects with a specific value for a key? 检查对象的jquery数组是否匹配键。 + =值,如果匹配,则推送新对象 - Check jquery array of objects for matching key. += value if match, push new object if not Javascript:从 object 中提取键值对并将它们分组到一个对象数组中 - Javascript: Extracting key value pairs from an object and grouping them together in an array of objects 对对象数组进行分组并为每个对象分配新的组合值 - Grouping an array of objects and assign new combined value to each object 使用一个 object 的值作为新 object 的键,从一组对象创建一个 object - Create an object from an array of objects using the value from one object as the key for the new object 从现有数组创建新的对象数组,匹配索引 - Creating new array of objects from existing arrays, matching on index 从对象数组中获取特定的值[{“ key”:“ value”},{“ key”:“ value”}] - Get specific value from array of objects [{“key”:“value”}, {“key”:“value”}] 使用从附加的 object 中取出的特定键创建对象数组 - Creating array of objects with specific key taken out of appended object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM