将数组转换为数组的数组
Transforming an array into an array of arrays
我正在尝试执行与展平数组相反的操作。
我有以下输入 JSON 个 4 个元素的数组:
[
{
"nestedObj": {
"id":12
}
},
{
"nestedObj": {
"id":555
}
},
{
"nestedObj": {
"id":555
}
},
{
"nestedObj" :{
"id":771
}
}
]
我想将它转换成一个数组的数组,其中每个子数组都有相同nestedObj.id
的元素组合在一起。
我可以假设初始 JSON 按 nestedObj.id
排序。
在上面的示例中,第 2 个和第 3 个元素的 nestedObj
的 id
是相同的 (555
),因此这些元素将被分组到一个子数组中。
这将是结果,一个 只有 3 个子数组元素的数组:
[
[{
"nestedObj": {
"id":12
}
}],
[{
"nestedObj": {
"id":555
}
},
{
"nestedObj": {
"id":555
}
}],
[{
"nestedObj" :{
"id":771
}
}]
]
这是让我得到我想要的东西的代码:
const data = [ /* ...the above input data... */ ];
let result = [];
let prevId = null;
for (let elem of data) {
let currId = elem.nestedObj.id;
if (currId === prevId) {
result[result.length - 1].push({...elem});
} else {
result.push([{...elem}]);
}
prevId = currId;
}
但是如您所见...代码非常具有声明性。从函数式编程的角度来看,它不是很 JavaScript。
我怎样才能使用例如重写它减少或其他 'modern JS' 技术?
只需将对象分组即可。
let array = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }],
result = Object.values(array.reduce((r, o) => {
(r[o.nestedObj.id] = r[o.nestedObj.id] || []).push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以使用函数 reduce
按 id 分组,使用函数 Object.values
提取分组值,最后 map
数组以构建所需的输出。
这是假设我们只有一个名为 nestedObj
的属性
let arr = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }],
result = Object.values(arr.reduce((a, {nestedObj: {id}}) => {
(a[id] || (a[id] = [])).push(id);
return a;
}, {})).map(r => r.map(id => ({nestedObj: {id}})));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
使用 Map 将具有相同 ID 的项目分组,然后从 Map 中获取最终值
const data = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }]
const map = new Map;
data.forEach(o => {
const {nestedObj:{id}} = o;
map.has(id) ? map.get(id).push(o) : map.set(id,[o]);
});
console.log([...map.values()])
我正在尝试执行与展平数组相反的操作。
我有以下输入 JSON 个 4 个元素的数组:
[
{
"nestedObj": {
"id":12
}
},
{
"nestedObj": {
"id":555
}
},
{
"nestedObj": {
"id":555
}
},
{
"nestedObj" :{
"id":771
}
}
]
我想将它转换成一个数组的数组,其中每个子数组都有相同nestedObj.id
的元素组合在一起。
我可以假设初始 JSON 按 nestedObj.id
排序。
在上面的示例中,第 2 个和第 3 个元素的 nestedObj
的 id
是相同的 (555
),因此这些元素将被分组到一个子数组中。
这将是结果,一个 只有 3 个子数组元素的数组:
[
[{
"nestedObj": {
"id":12
}
}],
[{
"nestedObj": {
"id":555
}
},
{
"nestedObj": {
"id":555
}
}],
[{
"nestedObj" :{
"id":771
}
}]
]
这是让我得到我想要的东西的代码:
const data = [ /* ...the above input data... */ ];
let result = [];
let prevId = null;
for (let elem of data) {
let currId = elem.nestedObj.id;
if (currId === prevId) {
result[result.length - 1].push({...elem});
} else {
result.push([{...elem}]);
}
prevId = currId;
}
但是如您所见...代码非常具有声明性。从函数式编程的角度来看,它不是很 JavaScript。
我怎样才能使用例如重写它减少或其他 'modern JS' 技术?
只需将对象分组即可。
let array = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }],
result = Object.values(array.reduce((r, o) => {
(r[o.nestedObj.id] = r[o.nestedObj.id] || []).push(o);
return r;
}, {}));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
您可以使用函数 reduce
按 id 分组,使用函数 Object.values
提取分组值,最后 map
数组以构建所需的输出。
这是假设我们只有一个名为 nestedObj
let arr = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }],
result = Object.values(arr.reduce((a, {nestedObj: {id}}) => {
(a[id] || (a[id] = [])).push(id);
return a;
}, {})).map(r => r.map(id => ({nestedObj: {id}})));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
使用 Map 将具有相同 ID 的项目分组,然后从 Map 中获取最终值
const data = [{ nestedObj: { id: 12 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 555 } }, { nestedObj: { id: 771 } }]
const map = new Map;
data.forEach(o => {
const {nestedObj:{id}} = o;
map.has(id) ? map.get(id).push(o) : map.set(id,[o]);
});
console.log([...map.values()])