首页 > 解决方案 > 如何通过JS中的三个不同属性对嵌套对象数组进行分组

问题描述

我有一组看起来像这样的对象

[
 {store: {id: "1", metadata: {itemName: "Q", itemCode: "332", itemDueDate: "2021-10-28", …}}},
 {store: {id: "2", metadata: {itemName: "WA", itemCode: "190", itemDueDate: "2021-08-23", …}}},
 {store: {id: "3", metadata: {itemName: "P", itemCode: "199", itemDueDate: "2020-12-03", …}}}
]

如何通过使用元数据对象中的三个不同属性对这个数组进行分组,所以它将是以下各项的组合:

  1. 项目名
  2. 项目代码
  3. 项目到期日

我尝试使用 Ramda 的 GroupWith,但我发现他们在分组时使用连续顺序。

export const groupedItems = (items: ArchiveItems) => R.groupWith<ArchiveItems>((a, b) => {
return a.store.metadata.itemName === b.store.metadata.itemName &&
       a.store.metadata.itemCode === b.store.metadata.itemCode &&
       a.store.metadata.itemDueDate === b.store.metadata.itemDueDate
})(items)

标签: javascriptarraystypescriptgroup-byramda.js

解决方案


是的,Ramda'sgroupWith是为对连续元素进行分组而设计的。 groupBy是你可能想要的。它需要一个函数,将您的对象转换为字符串,然后将您的数组分组为一个对象,每个转换后的字符串都有一个数组。您可以根据自己的喜好选择创建该字符串,最常见的是通过提取单个属性。在这里,我们可以将多个属性组合成一个字符串:

const collect = pipe (
  groupBy (({store: {metadata: m}}) => `${m.itemName}~${m.itemCode}~${m.itemDueDate}`),
  values
)

const data = [{store: {id: "1", metadata: {itemName: "Q", itemCode: "332", itemDueDate: "2021-10-28", foo: "a"}}}, {store: {id: "2", metadata: {itemName: "WA", itemCode: "190", itemDueDate: "2021-08-23", foo: "b"}}}, {store: {id: "3", metadata: {itemName: "P", itemCode: "199", itemDueDate: "2020-12-03", foo: "c"}}}, {store: {id: "4", metadata: {itemName: "WA", itemCode: "190", itemDueDate: "2021-08-23", foo: "d"}}}, {store: {id: "5", metadata: {itemName: "P", itemCode: "199", itemDueDate: "2020-12-03", foo: "e"}}}, {store: {id: "6", metadata: {itemName: "WA", itemCode: "190", itemDueDate: "2021-08-23", foo: "f"}}}]

console .log (
  collect (data)
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {pipe, groupBy, values} = R                           </script>

我在这里猜测了您的实际结构,因为您发布的内容不是合法的 JS。我还添加了其他项目,因为我们想演示当有实际重复时会发生什么。

请注意,最后的values调用将其转换为数组数组。您可以保留原始对象,但我想像这样的键"P~199~2020-12-03"不太可能很有帮助。或者您可能需要进行进一步处理才能实现您的基本目标。

如果您的某些值可能包含 a ~,则您可能需要不同的分隔符。


推荐阅读