将具有相同键的 JSON 对象合并在一起
Posted
技术标签:
【中文标题】将具有相同键的 JSON 对象合并在一起【英文标题】:Merging JSON objects with same key together 【发布时间】:2018-06-04 01:29:02 【问题描述】:我需要将具有相同键的 JSON 对象合并为一个对象或数组(不管结果是对象还是数组),其中包含键和值的数组
示例 JSON 对象:
[
"meine_frage": "hier kommt die antwort",
"ne_andere_frage": "ne andere antwort",
"was_willst_du": "alles",
"mehr_zur_auswahl": ["einiges", "vieles und", "g\u00e4r nix"]
,
"meine_frage": "tom & jerry",
"ne_andere_frage": "mickey maus",
"was_willst_du": "oder",
"mehr_zur_auswahl": ["manches", "einiges", "vieles und", "g\u00e4r nix"]
,
"meine_frage": "dick und doof",
"ne_andere_frage": "minnie muas",
"was_willst_du": "nichts",
"mehr_zur_auswahl": ["g\u00e4r nix"]
]
结果应该是这样的:
[
"meine_frage": ["hier kommt die antwort", "tom & jerry", "dick und doof"],
"ne_andere_frage": ["ne andere antwort", "mickey maus", "minnie muas"],
"was_willst_du": ["alles", "oder"],
"mehr_zur_auswahl": ["einiges", "vieles und", "g\u00e4r nix", "manches", "einiges", "vieles und", "g\u00e4r nix"]
]
有些值已经是数组,而有些不是,键是动态生成的,所以假设键名是未知的
我尝试使用 $.each 和 for 循环迭代键/值,但没有成功,还搜索了网络,但找不到类似的, 感谢任何帮助
【问题讨论】:
你的js代码在哪里? 感谢大家的快速解答 【参考方案1】:您可以为此使用reduce()
和concat()
方法。
const data = ["meine_frage":"hier kommt die antwort","ne_andere_frage":"ne andere antwort","was_willst_du":"alles","mehr_zur_auswahl":["einiges","vieles und","gär nix"],"meine_frage":"tom & jerry","ne_andere_frage":"mickey maus","was_willst_du":"oder","mehr_zur_auswahl":["manches","einiges","vieles und","gär nix"],"meine_frage":"dick und doof","ne_andere_frage":"minnie muas","was_willst_du":"nichts","mehr_zur_auswahl":["gär nix"]]
const result = data.reduce(function(r, e)
return Object.keys(e).forEach(function(k)
if(!r[k]) r[k] = [].concat(e[k])
else r[k] = r[k].concat(e[k])
), r
, )
console.log(result)
【讨论】:
这很好,非常接近实用。通过一些调整,您可以做到这一点:用三元 return 语句替换 if/else 和赋值,并在 array_map_associative 中使用该函数。【参考方案2】:您可以通过将callback
函数作为参数传递来使用reduce
方法。
算法如下:如果最终对象已经包含一个键,那么您应该用一个空的数组初始化该键的值。否则,您应该追加数组中所有项目的数组值。
let data = ["meine_frage":"hier kommt die antwort","ne_andere_frage":"ne andere antwort","was_willst_du":"alles","mehr_zur_auswahl":["einiges","vieles und","gär nix"],"meine_frage":"tom & jerry","ne_andere_frage":"mickey maus","was_willst_du":"oder","mehr_zur_auswahl":["manches","einiges","vieles und","gär nix"],"meine_frage":"dick und doof","ne_andere_frage":"minnie muas","was_willst_du":"nichts","mehr_zur_auswahl":["gär nix"]]
let result = data.reduce(function(obj, item)
Object.keys(item).forEach(function(key)
if(!obj[key]) obj[key] = [].concat(item[key])
else
if(Array.isArray(item[key]))
obj[key].push(...item[key])
else
obj[key].push(item[key]);
);
return obj;
,);
console.log([result]);
【讨论】:
【参考方案3】:这个函数可以完成工作:
const example = array =>
let newObject =
array.forEach((element) =>
for(let key in element)
if(typeof element[key] === 'object')
element[key].forEach((el) =>
if(newObject[key] && newObject[key].length)
newObject[key].push(el)
else
newObject[key] = [el]
)
else
if(newObject[key] && newObject[key].length)
newObject[key].push(element[key])
else
newObject[key] = [element[key]]
)
return newObject
【讨论】:
【参考方案4】:使用map
和Array.isArray
检查,试试下面的代码
var myArray = ["meine_frage": "hier kommt die antwort","ne_andere_frage": "ne andere antwort","was_willst_du": "alles","mehr_zur_auswahl": ["einiges", "vieles und", "g\u00e4r nix"], "meine_frage": "tom & jerry","ne_andere_frage": "mickey maus","was_willst_du": "oder","mehr_zur_auswahl": ["manches", "einiges", "vieles und", "g\u00e4r nix"], "meine_frage": "dick und doof","ne_andere_frage": "minnie muas","was_willst_du": "nichts","mehr_zur_auswahl": ["g\u00e4r nix"]];
var findKeyOf = function(key)
var temp = myArray.map(function(e)
return e[key];
);
var test = [];
for(let i in temp)
if(Array.isArray(temp[i]) )
test = test.concat(temp[i]);
else
test.push(temp[i])
return test;
;
var newArr = [
meine_frage:findKeyOf('meine_frage'),
ne_andere_frage:findKeyOf('ne_andere_frage'),
was_willst_du:findKeyOf('was_willst_du'),
mehr_zur_auswahl:findKeyOf('mehr_zur_auswahl'),
]
console.log(newArr);
【讨论】:
【参考方案5】:您可以使用array#reduce
作为累加器并遍历对象的每个键和array#concat
的值。
var data = [ "meine_frage": "hier kommt die antwort", "ne_andere_frage": "ne andere antwort", "was_willst_du": "alles", "mehr_zur_auswahl": ["einiges", "vieles und", "g\u00e4r nix"] , "meine_frage": "tom & jerry", "ne_andere_frage": "mickey maus", "was_willst_du":"oder", "mehr_zur_auswahl": ["manches", "einiges", "vieles und", "g\u00e4r nix"] , "meine_frage": "dick und doof", "ne_andere_frage": "minnie muas", "was_willst_du": "nichts", "mehr_zur_auswahl": ["g\u00e4r nix"] ];
var merged = data.reduce((r,o) =>
Object.keys(o).forEach(k =>
r[k] = (r[k] || []).concat(o[k]);
)
return r;
,);
console.log(merged);
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
【参考方案6】:使用reduce 和spread operator
var data = [
"meine_frage": "hier kommt die antwort",
"ne_andere_frage": "ne andere antwort",
"was_willst_du": "alles",
"mehr_zur_auswahl": ["einiges", "vieles und", "g\u00e4r nix"]
,
"meine_frage": "tom & jerry",
"ne_andere_frage": "mickey maus",
"was_willst_du": "oder",
"mehr_zur_auswahl": ["manches", "einiges", "vieles und", "g\u00e4r nix"]
,
"meine_frage": "dick und doof",
"ne_andere_frage": "minnie muas",
"was_willst_du": "nichts",
"mehr_zur_auswahl": ["g\u00e4r nix"]
]
let myData = data.reduce((b , a)=>
Object.keys(a).forEach(key =>
if (Object.keys(b).indexOf(key) > -1)
if (typeof a[key] === "object")
b[key] = [...b[key], ...a[key]]
else
b[key].push(a[key])
else
if (typeof a[key] === "object")
b[key] = [...a[key]]
else
b[key] = [a[key]]
)
return b
, )
console.log(myData)
.as-console-wrapper max-height: 100% !important; top: 0;
【讨论】:
你在哪里使用了破坏赋值? @MihaiAlexandru-Ionut,我更新了我的答案。这是spread operator
以上是关于将具有相同键的 JSON 对象合并在一起的主要内容,如果未能解决你的问题,请参考以下文章