我在通过键将JSON对象数组合并在一起时遇到了一些麻烦。有人会只使用Javascript有一个好的解决方案吗?
{
"code": "12345",
"error": "12345 error 1"
},
{
"code": "12345",
"error": "12345 error 2"
},
{
"code": "67890",
"error": "67890 error 1"
},
{
"code": "67890",
"error": "67890 error 2"
},
{
"code": "67890",
"error": "67890 error 3"
},
{
"code": "67890",
"error": "67890 error 4"
},
{
"code": "67890",
"error": "67890 error 5"
},
{
"code": "12092",
"error": "12092 error 1"
},
{
"code": "12092",
"error": "12092 error 2"
}
应转换为
{
"code": "12345",
"error": "12345 error 1, 12345 error 2"
},
{
"code": "67890",
"error": "67890 error 1, 67890 error 2, 67890 error 3, 67890 error 4, 67890 error 5"
},
{
"code": "12092",
"error": "12092 error 1, 12092 error 2"
}
任何帮助将不胜感激。我已经为此花费了很长时间,但似乎无法克服它。
答案 0 :(得分:4)
使用数组reduce
创建对象的新合并数组。在回调函数内部,检查累加器数组是否具有已经具有code
的对象。为此使用findIndex
。如果代码匹配,则更新error
。否则将当前对象推入累加器
const data = [{"code":"12345","error":"12345 error 1"},{"code":"12345","error":"12345 error 2"},{"code":"67890","error":"67890 error 1"},{"code":"67890","error":"67890 error 2"},{"code":"67890","error":"67890 error 3"},{"code":"67890","error":"67890 error 4"},{"code":"67890","error":"67890 error 5"},{"code":"12092","error":"12092 error 1"},{"code":"12092","error":"12092 error 2"}];
let mergedData = data.reduce(function(acc, curr) {
let findIndex = acc.findIndex(function(item) {
return item.code === curr.code;
})
if (findIndex === -1) {
acc.push(curr)
} else {
acc[findIndex].error += ', ' + curr.error
}
return acc;
}, []);
console.log(mergedData)
答案 1 :(得分:1)
使用Array#from,Array#reduce,Array#map和Map,您可以做这样的事情。
想法是首先使用Array#reduce和Map重新组合所有内容,然后将数据转换为使用Array#map寻求的输出。
const data = [{"code":"12345","error":"12345 error 1"},{"code":"12345","error":"12345 error 2"},{"code":"67890","error":"67890 error 1"},{"code":"67890","error":"67890 error 2"},{"code":"67890","error":"67890 error 3"},{"code":"67890","error":"67890 error 4"},{"code":"67890","error":"67890 error 5"},{"code":"12092","error":"12092 error 1"},{"code":"12092","error":"12092 error 2"}];
const res = Array.from(
data.reduce((a,{code, error})=>{
return a.set(code, [error].concat(a.get(code)||[]))
}, new Map())
).map(([code, error])=>({code, error: error.join(",")}));
console.log(res);
答案 2 :(得分:1)
使用Reduce并检查现有对象键的现有答案是完美的。
这是使用Map和其他ES6语法(for...of
)来完成此操作的另一种方法,我认为这很容易理解,并且是另一种有趣的方法:
const data = [{"code":"12345","error":"12345 error 1"},{"code":"12345","error":"12345 error 2"},{"code":"67890","error":"67890 error 1"},{"code":"67890","error":"67890 error 2"},{"code":"67890","error":"67890 error 3"},{"code":"67890","error":"67890 error 4"},{"code":"67890","error":"67890 error 5"},{"code":"12092","error":"12092 error 1"},{"code":"12092","error":"12092 error 2"}];
// Define a new empty Map.
const map = new Map();
// Loop through all data objects.
for (const dataEntry of data) {
// Check if we've already added this to our map; if not, add blank entry.
if (!map.has(dataEntry.code)) {
map.set(dataEntry.code, {code: dataEntry.code,error:[]});
}
// Append to the error property.
const mapEntry = map.get(dataEntry.code);
mapEntry.error.push(dataEntry.error);
}
// Flatten the error entries to be a single String instead of an Array.
for (const entry of map.values()) {
entry.error = entry.error.join(', ');
}
const output = Array.from(map.values());
console.log(output);