I am trying to create a new array of object from an existing array of object based on the common attribute (category.blocktitle) value inside the object. My array of object looks like this.
我试图根据对象内部的公共属性(category.blocktitle)值从现有的对象数组创建一个新的对象数组。我的对象数组看起来像这样。
[
{
"category": {
"name": "test1111",
"val": "test111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test22",
"val": "test2222",
"blocktitle": ".test.0.test2"
}
},
{
"category": {
"name": "test1111111",
"val": "test11111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test2222",
"val": "test222222",
"blocktitle": ".test.0.test2"
}
}
]
My desired output is
我想要的输出是
[
{
"category": {
"name_val" : [
{
"name": "test1111",
"val": "test111111111"
},
{
"name": "test1111111",
"val": "test11111111111",
}
]
},
"blocktitle": ".test.0"
},
{
"category": {
"name_val" : [
{
"name": "test22",
"val": "test2222"
},
{
"name": "test2222",
"val": "test222222",
}
]
},
"blocktitle": ".test.0.test2"
}
]
I have tried reduce / map / filter but not sure what I am doing wrong.
我尝试过reduce / map / filter但不确定我做错了什么。
5 个解决方案
#1
3
I would use ES6 Array.prototype.reduce
and Array.prototype.filter
methods:
我会使用ES6 Array.prototype.reduce和Array.prototype.filter方法:
let result = data.reduce((acc, d) => {
const found = acc.find(a => a.blocktitle === d.category.blocktitle);
const value = { name: d.category.name, val: d.category.val };
if(found) {
found.category.name_val.push(value);
}
else {
acc.push({blocktitle: d.category.blocktitle, category: { name_val: [value]} });
}
return acc;
}, []);
Where data
is your initial data array.
数据是您的初始数据数组。
#2
3
var test = [
{
"category": {
"name": "test1111",
"val": "test111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test22",
"val": "test2222",
"blocktitle": ".test.0.test2"
}
},
{
"category": {
"name": "test1111111",
"val": "test11111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test2222",
"val": "test222222",
"blocktitle": ".test.0.test2"
}
}
];
//create a map of blocktitle to elements with that blocktitle
var temp = test.reduce(function(collection, element){
if (collection[element.category.blocktitle] === undefined) collection[element.category.blocktitle] = [];
collection[element.category.blocktitle].push(element);
return collection;
}, {});
//convert temp to expected result
var result = Object.keys(temp).map(function(blocktitle){
return {
blocktitle: blocktitle,
category: {
name_val: temp[blocktitle].map(function(element){
return { name: element.category.name, val: element.category.val };
})
}
};
});
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#3
1
You could use an object as reference to the same group.
您可以使用对象作为同一组的引用。
var data = [{ category: { name: "test1111", val: "test111111111", blocktitle: ".test.0" } }, { category: { name: "test22", val: "test2222", blocktitle: ".test.0.test2" } }, { category: { name: "test1111111", val: "test11111111111", blocktitle: ".test.0" } }, { category: { name: "test2222", val: "test222222", blocktitle: ".test.0.test2" } }],
hash = Object.create(null),
grouped = [];
data.forEach(function (o) {
var key = o.category.blocktitle;
if (!hash[key]) {
hash[key] = [];
grouped.push({ category: { name_val: hash[key], blocktitle: o.category.blocktitle } });
}
hash[key].push({ name: o.category.name, val: o.category.val });
});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#4
1
You can use Array.prototype.reduce():
您可以使用Array.prototype.reduce():
const data = [{category: {name: 'test1111',val: 'test111111111',blocktitle: '.test.0'}},{category: { name: 'test22', val: 'test2222', blocktitle: '.test.0.test2' }},{category: {name: 'test1111111',val: 'test11111111111',blocktitle: '.test.0'}},{category: {name: 'test2222',val: 'test222222',blocktitle: '.test.0.test2'}}]
const result = data.reduce((a, c) => {
let blocktitle = c.category.blocktitle;
let objNameVal = { name: c.category.name, val: c.category.val };
if (a.hash[blocktitle]) {
let index = a.array.findIndex(e => e.blocktitle === blocktitle);
a.array[index].category.name_val.push(objNameVal);
} else {
a.hash[blocktitle] = true;
a.array.push({ category: { name_val: [objNameVal] }, blocktitle: blocktitle });
}
return a;
}, { array: [], hash: {} });
// Clean hash..
delete result.hash;
console.log(result.array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#5
0
You can use a reduce to index the items by blocktitle, and then map that object to an array.
您可以使用reduce通过blocktitle索引项目,然后将该对象映射到数组。
function convert(input) {
const byBlocktitle = input.reduce((byBlocktitleOut, inputObject) => {
const blocktitle = inputObject.category.blocktitle;
byBlocktitleOut[blocktitle] = byBlocktitleOut[blocktitle] || [];
byBlocktitleOut[blocktitle].push(inputObject);
return byBlocktitleOut;
}, {});
return Object.keys(byBlocktitle).map((blocktitle) => {
const inputObjects = byBlocktitle[blocktitle];
return {
category: {
name_val: inputObjects.map((inputObject) => {
return {
name: inputObject.category.name,
val: inputObject.category.val,
};
}),
},
blocktitle: blocktitle,
};
});
}
Working example/test: http://jsbin.com/yifapacupi/edit?js,console,output
工作示例/测试:http://jsbin.com/yifapacupi/edit?js,console,output
#1
3
I would use ES6 Array.prototype.reduce
and Array.prototype.filter
methods:
我会使用ES6 Array.prototype.reduce和Array.prototype.filter方法:
let result = data.reduce((acc, d) => {
const found = acc.find(a => a.blocktitle === d.category.blocktitle);
const value = { name: d.category.name, val: d.category.val };
if(found) {
found.category.name_val.push(value);
}
else {
acc.push({blocktitle: d.category.blocktitle, category: { name_val: [value]} });
}
return acc;
}, []);
Where data
is your initial data array.
数据是您的初始数据数组。
#2
3
var test = [
{
"category": {
"name": "test1111",
"val": "test111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test22",
"val": "test2222",
"blocktitle": ".test.0.test2"
}
},
{
"category": {
"name": "test1111111",
"val": "test11111111111",
"blocktitle": ".test.0"
}
},
{
"category": {
"name": "test2222",
"val": "test222222",
"blocktitle": ".test.0.test2"
}
}
];
//create a map of blocktitle to elements with that blocktitle
var temp = test.reduce(function(collection, element){
if (collection[element.category.blocktitle] === undefined) collection[element.category.blocktitle] = [];
collection[element.category.blocktitle].push(element);
return collection;
}, {});
//convert temp to expected result
var result = Object.keys(temp).map(function(blocktitle){
return {
blocktitle: blocktitle,
category: {
name_val: temp[blocktitle].map(function(element){
return { name: element.category.name, val: element.category.val };
})
}
};
});
console.log(result);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
#3
1
You could use an object as reference to the same group.
您可以使用对象作为同一组的引用。
var data = [{ category: { name: "test1111", val: "test111111111", blocktitle: ".test.0" } }, { category: { name: "test22", val: "test2222", blocktitle: ".test.0.test2" } }, { category: { name: "test1111111", val: "test11111111111", blocktitle: ".test.0" } }, { category: { name: "test2222", val: "test222222", blocktitle: ".test.0.test2" } }],
hash = Object.create(null),
grouped = [];
data.forEach(function (o) {
var key = o.category.blocktitle;
if (!hash[key]) {
hash[key] = [];
grouped.push({ category: { name_val: hash[key], blocktitle: o.category.blocktitle } });
}
hash[key].push({ name: o.category.name, val: o.category.val });
});
console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#4
1
You can use Array.prototype.reduce():
您可以使用Array.prototype.reduce():
const data = [{category: {name: 'test1111',val: 'test111111111',blocktitle: '.test.0'}},{category: { name: 'test22', val: 'test2222', blocktitle: '.test.0.test2' }},{category: {name: 'test1111111',val: 'test11111111111',blocktitle: '.test.0'}},{category: {name: 'test2222',val: 'test222222',blocktitle: '.test.0.test2'}}]
const result = data.reduce((a, c) => {
let blocktitle = c.category.blocktitle;
let objNameVal = { name: c.category.name, val: c.category.val };
if (a.hash[blocktitle]) {
let index = a.array.findIndex(e => e.blocktitle === blocktitle);
a.array[index].category.name_val.push(objNameVal);
} else {
a.hash[blocktitle] = true;
a.array.push({ category: { name_val: [objNameVal] }, blocktitle: blocktitle });
}
return a;
}, { array: [], hash: {} });
// Clean hash..
delete result.hash;
console.log(result.array);
.as-console-wrapper { max-height: 100% !important; top: 0; }
#5
0
You can use a reduce to index the items by blocktitle, and then map that object to an array.
您可以使用reduce通过blocktitle索引项目,然后将该对象映射到数组。
function convert(input) {
const byBlocktitle = input.reduce((byBlocktitleOut, inputObject) => {
const blocktitle = inputObject.category.blocktitle;
byBlocktitleOut[blocktitle] = byBlocktitleOut[blocktitle] || [];
byBlocktitleOut[blocktitle].push(inputObject);
return byBlocktitleOut;
}, {});
return Object.keys(byBlocktitle).map((blocktitle) => {
const inputObjects = byBlocktitle[blocktitle];
return {
category: {
name_val: inputObjects.map((inputObject) => {
return {
name: inputObject.category.name,
val: inputObject.category.val,
};
}),
},
blocktitle: blocktitle,
};
});
}
Working example/test: http://jsbin.com/yifapacupi/edit?js,console,output
工作示例/测试:http://jsbin.com/yifapacupi/edit?js,console,output