有这样一个数组数组:
let arr = [
[
{"key":2, "other":123},
{"key":2, "other":222}
],
[
{"key":3, "other":0}
],
[
{"key":1, "other":11},
{"key":1, "other":23}
],
[
{"key":1, "other":22}
]
]
我需要获取此arr
,但要使分组数组的第一个元素的“键”值相同,所以它看起来像:
let arr = [
[
{"key":2, "other":123},
{"key":2, "other":222}
],
[
{"key":3, "other":0}
],
[
[
{"key":1, "other":11},
{"key":1, "other":23}
],
[
{"key":1, "other":22}
]
],
]
我尝试使用reduce函数,但结果完全不同。
let final = []
for (let i=0; i<arr.length; i++) {
let arr1 = i==0?arr:arr.slice(i)
let final1 = arr1.reduce((acc,x)=> {
acc = acc[0].key==x[0].key?acc.concat(x):acc
return acc
})
arr1.length>1&&final.push(final1)
}
在此代码中,问题在于它将arr [1]与arr [2],arr [3]进行比较,然后再次将arr [2]与arr [3]进行比较并将其分组(即使arr [1] .key和arr [2] .key和arr [3] .key相同)您能给出一些提示或给出最终的功能吗?
答案 0 :(得分:1)
创建keys
的对象及其计数。然后,您可以过滤多次出现的键,即(count >= 2)
。然后使用reduce
遍历您的输入数组,并查看它存在于过滤后的数组键中,如果是,则推入单独的数组,其他为accu
。然后将两个数组合并为一个。
let input = [
[
{"key":2, "other":123},
{"key":2, "other":222}
],
[
{"key":3, "other":0}
],
[
{"key":1, "other":11},
{"key":1, "other":23}
],
[
{"key":1, "other":22}
]
];
// keys with unique key and its count. filter whose count are greater than two.
const groupByArrKeysOccurence = input.reduce((accu, arr) => {
const key = arr[0].key;
accu[key] = (accu[key] || 0) + 1;
return accu;
}, {});
const filteredKeys = Object.entries(groupByArrKeysOccurence).filter(([_, val]) => val > 1).map(([key, _]) => Number(key));
const multipleArrOccurenceKeys = [];
const singleArrOccurenceKeys = input.reduce((accu, arr) => {
const isKey = arr.some(({key}) => filteredKeys.includes(key));
if(isKey) {
multipleArrOccurenceKeys.push(arr);
} else {
accu.push(arr);
}
return accu;
}, []);
console.log([...singleArrOccurenceKeys, multipleArrOccurenceKeys]);
答案 1 :(得分:1)
let arr = [
[
{"key":2},
{"key":2}
],
[
{"key":3}
],
[
{"key":1},
{"key":1}
],
[
{"key":1}
]
]
var myMap = new Map();
for (i = 0; i < arr.length; i++) {
if(!myMap.has(arr[i][0]['key'])){
myMap.set(arr[i][0]['key'],i)
}else if(myMap.get(arr[i][0]['key'])===undefined){
myMap.set(arr[i][0]['key'],i)
}else{
myMap.set(arr[i][0]['key'],myMap.get(arr[i][0]['key'])+','+i)
}
}
var out =[];
for(var v of myMap.values()){
var s = String(v).split(",");
var fi = s[0]
var subarray =[]
for(var i in s){
subarray.push(arr[s[i]])
}
out[fi] = subarray;
}
您将在数组外找到响应。希望它对您有用
答案 2 :(得分:0)
我认为您想要这样的内容,请尝试运行代码段
let arr = [
[
{
"key": 2
},
{
"key": 2
}
],
[
{
"key": 3
}
],
[
{
"key": 1
},
{
"key": 1
}
],
[
{
"key": 1
}
]
]
let result = arr.reduce((res, array) => {
array.forEach((value, index) => {
const obj = res.find(a => {
return !!a.find(({key}) => {
return key === value.key
})
})
if (obj) {
obj.push(value)
} else {
res.push([value])
}
})
return res;
}, [])
console.log(result);
答案 3 :(得分:0)
此解决方案无法产生您想要的确切结果,但是它很好而且干净。您想要的结果很可能会在将来给您带来麻烦,因为某些元素比其他元素嵌套得更多。
此答案假定每个数组始终至少有一个元素,因为问题是按第一个元素键分组。
let arr = [[{"key":2, "other":123}, {"key":2, "other":222}], [{"key":3, "other":0}], [{"key":1, "other":11}, {"key":1, "other":23}], [{"key":1, "other":22}]];
let groups = {};
let group = key => groups[key] || (groups[key] = []);
arr.forEach(arr => group(arr[0].key).push(arr));
console.log(groups);
console.log(Object.values(groups));
// If you want to get the result you're looking for (not looking at the
// order), you can simply flatten all groups of 1 element. Although
// depending on your use case I recommend sticking with the above.
console.log(Object.values(groups).map(group => group.length === 1 ? group[0] : group));