我正在尝试对一组对象进行嵌套分组。
这个要点提供的功能几乎按预期工作,并使用 lodash 作为基础:
https://gist.github.com/joyrexus/9837596
const _ = require('lodash');
function nest(seq, keys) {
if (!keys.length) return seq;
let [first, ...rest] = keys;
return _.mapValues(_.groupBy(seq, first), value => nest(value, rest));
}
这是递归的,
但是,我面临两个问题。
- 如果一个参数设置为
null
或undefined
,它被用作一个组,而不是 - 一个可选的对象属性应该被用作最终的对象键,所以只有对象,没有数组。此属性始终必须是唯一的才能正常工作。
是否可以结合或扩展现有的nest
功能来解决以上几点?
这种方法的优点是,除了键,我还可以使用函数数组 (p => p.parameterGroup1
) 来返回参数。因此,除了最后一个可选参数,我还可以使用 p => p.parameterGroup1 吗? p.parameterGroup1 : p.label
我准备了一个小测试,让你更好地了解预期的结果:
test('nest array of objects by groups as keys, stopping at null and using a final label param', t => {
let properties = [
{
parameterGroup1: 'first',
parameterGroup2: 'second',
parameterGroup3: 'third',
label: 'A'
},
{
parameterGroup1: 'first',
parameterGroup2: 'second',
parameterGroup3: null,
label: 'B'
},
{
parameterGroup1: 'a',
parameterGroup2: 'b',
parameterGroup3: undefined,
label: 'C'
},
]
let expected = {
first: {
second: {
third: {
A: {
parameterGroup1: 'first',
parameterGroup2: 'second',
parameterGroup3: 'third',
label: 'A'
}
},
B: {
parameterGroup1: 'first',
parameterGroup2: 'second',
parameterGroup3: null,
label: 'B'
}
}
},
a: {
b: {
C: {
parameterGroup1: 'a',
parameterGroup2: 'b',
parameterGroup3: undefined,
label: 'C'
}
}
}
}
let grouped = nest(properties, ['parameterGroup1', 'parameterGroup2', 'parameterGroup3'], 'label')
t.deepEqual(grouped, expected)
})
提前致谢!
最佳答案
这是在 vanilla js 中实现的一种方法。我们通过reduce
数组seq
构造result
对象:对于数组中的每个对象
,我们使用来自 obj
seqkeys
的键的 obj
的值逐层遍历 result
对象。如果该值为 null
或 undefined
,我们将跳过(不会再往下一层)。如果该值存在,我们将下降一个级别,如果它尚不存在,则创建一个级别(对象)。我们在 keys
数组上使用 reduce
重复执行此操作,直到找到叶对象(最后一级),我们将当前对象分配给评估 获得的键>obj[最后一个]
:
function nest(seq, keys, last) {
return seq.reduce((result, obj) => {
// First we find the (last level) object to which we will assign our current object to, as a child
let lastLevel = keys.reduce((res, key) => { // for each key in keys
let value = obj[key]; // get the value from our current object obj for that key key
if(value == null) return res; // if the value is null or undefined, skip
if(res[value]) return res[value]; // if the level for value exists return it
return res[value] = {}; // if it doesn't, create a new level, assing it to result and return it
}, result);
// then we assign it using the value of the key last
lastLevel[obj[last]] = obj; // we found the last possible level, assign obj to it under the key obj[last]
return result;
}, {});
}
示例:
function nest(seq, keys, last) {
return seq.reduce((result, obj) => {
let lastLevel = keys.reduce((res, key) => {
let value = obj[key];
if(!value) return res;
if(res[value]) return res[value];
return res[value] = {};
}, result);
lastLevel[obj[last]] = obj;
return result;
}, {});
}
let properties = [{parameterGroup1: 'first',parameterGroup2: 'second',parameterGroup3: 'third',label: 'A'},{parameterGroup1: 'first',parameterGroup2: 'second',parameterGroup3: null,label: 'B'},{parameterGroup1: 'a',parameterGroup2: 'b',parameterGroup3: undefined,label: 'C'}];
let grouped = nest(properties, ['parameterGroup1', 'parameterGroup2', 'parameterGroup3'], 'label');
console.log(grouped);
关于javascript - 按属性嵌套/分组对象数组,忽略 null/undefined 并使用附加属性作为标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50213743/