gpt4 book ai didi

javascript - 使用 JavaScript (ES5) 进行嵌套分组

转载 作者:行者123 更新时间:2023-11-29 17:46:26 25 4
gpt4 key购买 nike

我有一个对象数组如下:

    [
{"id":1,"lib":"A","categoryID":10,"categoryTitle":"Cat10","moduleID":"2","moduleTitle":"Module 2"},
{"id":2,"lib":"B","categoryID":10,"categoryTitle":"Cat10","moduleID":"2","moduleTitle":"Module 2"},
...
{"id":110,"lib":"XXX","categoryID":90,"categoryTitle":"Cat90","moduleID":"4","moduleTitle":"Module 4"}
]

我想按 (moduleID,moduleTitle) 对这个数组进行分组,然后按 (categoryID,categoryTitle ).

这是我试过的:

function groupBy(data, id, text) {

return data.reduce(function (rv, x) {
var el = rv.find(function(r){
return r && r.id === x[id];
});
if (el) {
el.children.push(x);
} else {
rv.push({ id: x[id], text: x[text], children: [x] });
}
return rv;
}, []);

}

var result = groupBy(response, "moduleID", "moduleTitle");

result.forEach(function(el){
el.children = groupBy(el.children, "categoryID", "categoryTitle");
});

上面的代码按预期工作,但如您所见,在第一次分组后,我不得不再次迭代按 moduleId 分组的数组,以便按 分组>categoryId.

如何修改这段代码,以便我只能在数组上调用一次 groupBy 函数?

编辑:

抱歉,这可能会迟到,但我希望通过使用 ES5 来完成,不要使用 Shim,也不要使用 Polyfill。

最佳答案

这是一种可能的(虽然可能有点高级)方法:

class DefaultMap extends Map {
constructor(factory, iter) {
super(iter || []);
this.factory = factory;
}

get(key) {
if (!this.has(key))
this.set(key, this.factory());
return super.get(key);
}
}

基本上,它是 Map 在缺少值时调用工厂函数。现在,有趣的部分:

let grouper = new DefaultMap(() => new DefaultMap(Array));

for (let item of yourArray) {
let firstKey = item.whatever;
let secondKey = item.somethingElse;
grouper.get(firstKey).get(secondKey).push(item);
}

对于每个 firstKey,这会在 grouper 中创建一个 Map,并且这些映射的值是按第二个键分组的数组。

您的问题中更有趣的部分是您使用的是复合键,这在 JS 中非常棘手,因为它(几乎)不提供不可变的数据结构。考虑:

items = [
{a: 'one', b: 1},
{a: 'one', b: 1},
{a: 'one', b: 2},
{a: 'two', b: 2},
]

let grouper = new DefaultMap(Array);

for (let x of items) {
let key = [x.a, x.b]; // wrong!
grouper.get(key).push(x);
}

因此,我们天真地通过复合键对对象进行分组,并期望在我们的石斑鱼中看到 ['one', 1] 下的两个对象(为了示例,这是一个级别).当然,这是行不通的,因为每个 key 都是一个新创建的数组,而且对于 Map 或任何其他键控存储而言,它们都是不同的。

一个可能的解决方案是为每个键创建一个不可变的结构。一个明显的选择是使用 Symbol,例如

let tuple = (...args) => Symbol.for(JSON.stringify(args))

然后

for (let x of items) {
let key = tuple(x.a, x.b); // works
grouper.get(key).push(x);
}

关于javascript - 使用 JavaScript (ES5) 进行嵌套分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49033570/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com