使用 lodash 进行多级分组和填充数组
Multi level grouping and populate arrays with using lodash
我在看下面的例子。
但是我需要多次分组,如下例所示。我应该怎么办?谢谢
[
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
至
[
{
birthdate: "1993",
birthdateDetail: [
{
category: "a",
categoryDetail: [
{ day: "12", name: "Ben" },
{ day: "13", name: "John" },
],
},
{
category: "b",
categoryDetail: [{ day: "14", name: "Larry" }],
},
],
},
{
birthdate: "1994",
birthdateDetail: [{ category: "", day: "15", name: "Nicole" }],
},
];
您的方向正确:使用 _.groupBy
将帮助您对数据进行分组,但由于您需要两层嵌套,因此需要 运行 两次:
- 顶层是按
birthdate
分组
- 第二层按
category
分组
因为 _.groupBy
returns an object, we will need to use Object.entries
将键值对转换为适合您想要的形状的对象数组。
在第二层,我们需要进行最后一次迭代以确保从嵌套数据中删除 category
和 birthday
键。
请参阅下面的概念验证:
const data = [
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
// Top level: group by birthdate
const dataByBirthdate = _.groupBy(data, d => d.birthdate);
// Convert object into array of objects
const transformedData = Object.entries(dataByBirthdate).map(entry => {
const [birthdate, value] = entry;
// Second level: group by category
const birthdatedetailByCategory = _.groupBy(value, d => d.category);
const birthdatedetail = Object.entries(birthdatedetailByCategory).map(entry => {
const [category, value] = entry;
// Step through all entries to ensure we remove keys of your selection
const categorydetail = value.map(d => {
delete d.birthdate;
delete d.category;
return d;
});
return { category, categorydetail };
});
return { birthdate, birthdatedetail };
});
console.log(transformedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
这是用 lodash 对数组进行分组的函数:
const formatedResponse = _(arr)
.groupBy("birthdate")
.map((items, birthdate) => {
const birthdateDetails = _(items)
.groupBy("category")
.map((items, category) => {
return {
category,
categoryDetails: items.map(({ day, name }) => ({ day, name }))
};
})
.value();
return {
birthdate,
birthdateDetails
};
})
.value();
您可以使用一种抽象方法进行分组,方法是采用一个对象,该对象保留每个级别的键以及所需的结果结构。
这种方法适用于任意嵌套。
const
data = [{ birthdate: "1993", day: "12", category: "a", name: "Ben" }, { birthdate: "1993", day: "13", category: "a", name: "John" }, { birthdate: "1993", day: "14", category: "b", name: "Larry" }, { birthdate: "1994", day: "15", category: "", name: "Nicole" }],
groups = ['birthdate', 'category'],
getEmpty = () => ({ _: [] }),
result = data
.reduce((q, o) => {
groups
.reduce((r, k) => {
const v = o[k];
if (!v) return r;
if (!r[v]) r._.push({ [k]: v, [k + 'Detail']: (r[v] = getEmpty())._ });
return r[v];
}, q)
._
.push(o);
return q;
}, getEmpty())
._;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
可能是这样的
const data = [
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
const group = (data) => {
return _(data)
.groupBy('birthdate')
.map((birthdateItems, birthdate) => ({
birthdate,
birthdateDetail: _(birthdateItems)
.groupBy('category')
.map((catgoryItems, category) => ({
category,
categoryDetail: _(catgoryItems)
.map(item => _.omit(item, ['birthdate', 'category']))
.value()
}))
.value()
}))
.value();
}
console.log(group(data));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>
我在看下面的例子
但是我需要多次分组,如下例所示。我应该怎么办?谢谢
[
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
至
[
{
birthdate: "1993",
birthdateDetail: [
{
category: "a",
categoryDetail: [
{ day: "12", name: "Ben" },
{ day: "13", name: "John" },
],
},
{
category: "b",
categoryDetail: [{ day: "14", name: "Larry" }],
},
],
},
{
birthdate: "1994",
birthdateDetail: [{ category: "", day: "15", name: "Nicole" }],
},
];
您的方向正确:使用 _.groupBy
将帮助您对数据进行分组,但由于您需要两层嵌套,因此需要 运行 两次:
- 顶层是按
birthdate
分组
- 第二层按
category
分组
因为 _.groupBy
returns an object, we will need to use Object.entries
将键值对转换为适合您想要的形状的对象数组。
在第二层,我们需要进行最后一次迭代以确保从嵌套数据中删除 category
和 birthday
键。
请参阅下面的概念验证:
const data = [
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
// Top level: group by birthdate
const dataByBirthdate = _.groupBy(data, d => d.birthdate);
// Convert object into array of objects
const transformedData = Object.entries(dataByBirthdate).map(entry => {
const [birthdate, value] = entry;
// Second level: group by category
const birthdatedetailByCategory = _.groupBy(value, d => d.category);
const birthdatedetail = Object.entries(birthdatedetailByCategory).map(entry => {
const [category, value] = entry;
// Step through all entries to ensure we remove keys of your selection
const categorydetail = value.map(d => {
delete d.birthdate;
delete d.category;
return d;
});
return { category, categorydetail };
});
return { birthdate, birthdatedetail };
});
console.log(transformedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
这是用 lodash 对数组进行分组的函数:
const formatedResponse = _(arr)
.groupBy("birthdate")
.map((items, birthdate) => {
const birthdateDetails = _(items)
.groupBy("category")
.map((items, category) => {
return {
category,
categoryDetails: items.map(({ day, name }) => ({ day, name }))
};
})
.value();
return {
birthdate,
birthdateDetails
};
})
.value();
您可以使用一种抽象方法进行分组,方法是采用一个对象,该对象保留每个级别的键以及所需的结果结构。
这种方法适用于任意嵌套。
const
data = [{ birthdate: "1993", day: "12", category: "a", name: "Ben" }, { birthdate: "1993", day: "13", category: "a", name: "John" }, { birthdate: "1993", day: "14", category: "b", name: "Larry" }, { birthdate: "1994", day: "15", category: "", name: "Nicole" }],
groups = ['birthdate', 'category'],
getEmpty = () => ({ _: [] }),
result = data
.reduce((q, o) => {
groups
.reduce((r, k) => {
const v = o[k];
if (!v) return r;
if (!r[v]) r._.push({ [k]: v, [k + 'Detail']: (r[v] = getEmpty())._ });
return r[v];
}, q)
._
.push(o);
return q;
}, getEmpty())
._;
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
可能是这样的
const data = [
{ birthdate: "1993", day: "12", category: "a", name: "Ben" },
{ birthdate: "1993", day: "13", category: "a", name: "John" },
{ birthdate: "1993", day: "14", category: "b", name: "Larry" },
{ birthdate: "1994", day: "15", category: "", name: "Nicole" },
];
const group = (data) => {
return _(data)
.groupBy('birthdate')
.map((birthdateItems, birthdate) => ({
birthdate,
birthdateDetail: _(birthdateItems)
.groupBy('category')
.map((catgoryItems, category) => ({
category,
categoryDetail: _(catgoryItems)
.map(item => _.omit(item, ['birthdate', 'category']))
.value()
}))
.value()
}))
.value();
}
console.log(group(data));
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script>