给定以下数据集
const data = [
{
id: 1,
name: "zoro",
specie: "dog",
age: 3,
size: "big",
location: {
city: "city 1",
town: "city 1",
},
},
{
id: 2,
name: "nami",
specie: "dog",
age: 5,
size: "small",
location: {
city: "city 1",
town: "city 11",
},
},
{
id: 3,
name: "ocho",
specie: "cat",
age: 9,
size: "small",
location: {
city: "city x",
town: "city x",
},
},
];
我正试图通过对象数组的一些属性来获取它的摘要。细节是这些属性的一些值是其他对象,例如location
为了获得摘要,我做了以下
function tally(array, key) {
return array.reduce((previous, current) => {
previous[current[key]] = (previous[current[key]] || 0) + 1;
return previous;
}, {});
}
通过这种方式,我得到以下结果
const specieTally = tally(data, "specie"); // { dog: 2, cat: 1 }
const ageTally = tally(data, "age"); // { '3': 1, '5': 1, '9': 1 }
const sizeTally = tally(data, "size"); // { big: 1, small: 2 }
const locationTally = tally(data, "location.city"); // { undefined: 3 }
如您所见,locationTally
的结果不正确。为了向前推进,我对这种可能的情况进行了手动验证。示例:
function tally(array, key) {
return array.reduce((previous, current) => {
if (key === "location.city") {
previous[current["location"]["city"]] = (previous[current["location"]["city"]] || 0) + 1;
} else {
previous[current[key]] = (previous[current[key]] || 0) + 1;
}
return previous;
}, {});
}
因此,输出如下:
const locationTally = tally(data, "location.city"); // { 'city 1': 2, 'city x': 1 }
这暂时解决了问题,但我想知道如何通过编程获得相同的结果
您可以尝试以下操作:
const data = [
{
id: 1,
name: "zoro",
specie: "dog",
age: 3,
size: "big",
location: {
city: "city 1",
town: "city 1",
},
},
{
id: 2,
name: "nami",
specie: "dog",
age: 5,
size: "small",
location: {
city: "city 1",
town: "city 11",
},
},
{
id: 3,
name: "ocho",
specie: "cat",
age: 9,
size: "small",
location: {
city: "city x",
town: "city x",
},
},
];
function tally(array, key) {
return array.reduce((previous, current) => {
if (key.indexOf('.') !== -1) {
let keys = key.split('.');
previous[getNestedValue(current, keys)] = (previous[getNestedValue(current, keys)] || 0) + 1;
} else {
previous[current[key]] = (previous[current[key]] || 0) + 1;
}
return previous;
}, {});
}
function getNestedValue(element, keys) {
let value = element;
keys.forEach(key => {
value = value[key];
})
return value;
}
const locationTally = tally(data, "location.city");
console.log(locationTally);
在这里,我们用一个点字符(如果存在(来分割键,然后使用一个函数来获得确切的嵌套值,该函数在分割的键上循环,并在每次迭代中深入,直到它到达末尾。不过,您可能需要添加适当的空检查。
您只需要解析密钥,使用数组减少
const data =
[{id:1,name:'zoro',specie:'dog',age:3,size:'big',location:{city:'city 1',town:'city 1'}},{id:2,name:'nami',specie:'dog',age:5,size:'small',location:{city:'city 1',town:'city 11'}},{id:3,name:'ocho',specie:'cat',age:9,size:'small',location:{city:'city x',town:'city x'}}]
, tally =
(arr, key) => arr.reduce((acc, arrElm) =>
{
let ref = key.split('.').reduce((o,k) => o[k], arrElm)
acc[ref] = (acc[ref] || 0) + 1;
return acc;
}
, {})
, specieTally = tally( data, 'specie' ) // { dog: 2, cat: 1 }
, ageTally = tally( data, 'age' ) // { '3': 1, '5': 1, '9': 1 }
, sizeTally = tally( data, 'size' ) // { big: 1, small: 2 }
, locationTally = tally( data, 'location.city' ) // { 'city 1': 2, 'city x': 1 }
;
console.log ('specieTally:', specieTally, 'nageTally:', ageTally, 'nsizeTally:', sizeTally, 'nlocationTally:', locationTally )
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}