我正在尝试根据数组中JSON元素的属性将JSON数组转换为地图。
这是JSON数组的结构:
[
{"property1": "x","property2": "value1","property3": "value1"},
{"property1": "x","property2": "value2","property3": "value2"},
{"property1": "y","property2": "value3","property3": "value3"},
{"property1": "y","property2": "value4","property3": "value4"}
]
我想将JSON数组拆分成这样的映射:
{
"x": [{"property2": "value1","property3": "value1"},
{"property2": "value2","property3": "value2"}],
"y": [{"property2": "value3","property3": "value3"},
{"property2": "value4","property3": "value4"}]
}
我该如何使用Javascript?
(PS:我是Java的新手)
答案 0 :(得分:2)
JavaScript的地图有Map
,因此您可以这样做:
const data = [{"property1": "x","property2": "value1","property3": "value1"},{"property1": "x","property2": "value2","property3": "value2"},{"property1": "y","property2": "value3","property3": "value3"},{"property1": "y","property2": "value4","property3": "value4"}];
const map = new Map(data.map(o => [o.property1, []]));
data.forEach(({property1, ...rest}) => map.get(property1).push(rest));
const result = Object.fromEntries(map);
console.log(result);
如果您不喜欢使用Maps,最后一次分配会将Map
转换为普通对象。
Map
,箭头功能,对象文字扩展语法等在ES5中不可用。在该版本的JavaScript中,您可以执行以下操作:
const data = [{"property1": "x","property2": "value1","property3": "value1"},{"property1": "x","property2": "value2","property3": "value2"},{"property1": "y","property2": "value3","property3": "value3"},{"property1": "y","property2": "value4","property3": "value4"}];
var map = {}
data.forEach(function (o) {
var cpy = Object.assign({}, o);
delete cpy.property1;
map[o.property1] = (map[o.property1] || []).concat(cpy);
});
console.log(map);
答案 1 :(得分:0)
尝试以下代码:
let a = [{
"property1": "x",
"property2": "value1",
"property3": "value1"
},
{
"property1": "x",
"property2": "value2",
"property3": "value2"
},
{
"property1": "y",
"property2": "value3",
"property3": "value3"
},
{
"property1": "y",
"property2": "value4",
"property3": "value4"
}
];
let b = {};
for (o of a) {
b[o.property1] = b[o.property1] || [];
b[o.property1].push({
property2: o.property2,
property3: o.property3
});
}
console.log(b);
此代码的作用是,首先为每个array
创建一个property1
属性(如果尚不存在)。然后,它仅使用property2
和property3
将新对象推送到该数组中。
答案 2 :(得分:0)
对于功能性方法,您可以使用Object.values:
var o = [
{"property1": "x","property2": "value1","property3": "value1"},
{"property1": "x","property2": "value2","property3": "value2"},
{"property1": "y","property2": "value3","property3": "value3"},
{"property1": "y","property2": "value4","property3": "value4"}
]
var r = Object.values(o).reduce((ac, x) => ({
...ac,
[x.property1]: [
...(ac[x.property1] || []),
x
]
}), {})
console.log(r)
答案 3 :(得分:0)
您可以通过Array.reduce获取此信息,然后确定是要使用对象文字还是Map开头:
使用地图:
let data = [{ "property1": "x", "property2": "value1", "property3": "value1" }, { "property1": "x", "property2": "value2", "property3": "value2" }, { "property1": "y", "property2": "value3", "property3": "value3" }, { "property1": "y", "property2": "value4", "property3": "value4" } ]
let result = data.reduce((r,{property1, property2, property3}) =>
r.set(property1, { property2, property3 }), new Map())
console.log(Object.fromEntries(result))
使用对象文字作为累加器:
let data = [{ "property1": "x", "property2": "value1", "property3": "value1" }, { "property1": "x", "property2": "value2", "property3": "value2" }, { "property1": "y", "property2": "value3", "property3": "value3" }, { "property1": "y", "property2": "value4", "property3": "value4" } ]
let result = data.reduce((r,{property1, property2, property3}) => {
r[property1] = r[property1] || []
r[property1].push({ property2, property3 })
return r
}, {})
console.log(result)
答案 4 :(得分:-1)
这是我解决这个问题的方法。我绝不是专家,我相信其他用户可以提供更好的解决方案。但是直到那时您都可以看到是否有帮助。
基本上,我们想使用.filter表达式过滤掉两个集合(x和y)。然后,对于这些集合,我们将删除用于过滤的属性。然后最后创建一个将其余集合组合在一起的新对象。
JSFiddle:https://jsfiddle.net/u9bxg8wv/1/
const dataSource = [
{"property1": "x","property2": "value1","property3": "value1"},
{"property1": "x","property2": "value2","property3": "value2"},
{"property1": "y","property2": "value3","property3": "value3"},
{"property1": "y","property2": "value4","property3": "value4"}
];
let xContainer = dataSource.filter(x => x.property1 === "x");
let yContainer = dataSource.filter(y => y.property1 === "y");
xContainer.forEach((e) => {
delete e.property1;
});
yContainer.forEach((e) => {
delete e.property1;
});
let mappedDataSource = {
"x": xContainer,
"y": yContainer
};
console.log(mappedDataSource);