【问题标题】:Using reduce and sort together (JavaScript)一起使用 reduce 和排序 (JavaScript)
【发布时间】:2021-07-27 02:25:30
【问题描述】:

我有一个对象数组 (groceryArray),我想通过 groupId 属性(对象键)将它们组织成一个对象,最后通过 groupDisplayOrder 属性对这些键进行排序。请参阅 finalOutput 以获得所需的结果。

const groceryArray = [
    { id: 'apples', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 },
    { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 },
    { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 },
    { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }
]

期望的结果

const finalOutput = {
    produce: [{ id: 'apples', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 }],
    dairy: [{ id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 }],
    meat: [{ id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 }],
    seafood: [{ id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 }, { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }]
}

这是我当前的代码......我想我可能做了太多的步骤。我想知道是否有一种方法可以同时减少和排序?

  const groceriesGroupedById = groceryArray.reduce((acc, cur) => {
    if (cur.groupId) {
      (acc[cur.groupId] || (acc[cur.groupId] = [])).push(cur)
    }
    return acc
  }, {})

  const sortedGroupIds = Object.keys(groceriesGroupedById).sort((a, b) => {
    return groceriesGroupedById[a][0].groupDisplayOrder - groceriesGroupedById[b][0].groupDisplayOrder
  })

  const finalOutput = sortedGroupIds.reduce((acc, key) => ( acc[key] = groceriesGroupedById[key], acc ), {})

【问题讨论】:

  • 谁关闭了这个?你能重新打开吗...这是不同的,因为我要求分组和排序...

标签: javascript arrays object ecmascript-6 reduce


【解决方案1】:

首先,使用Array.sort()对数组进行排序并使用Array.reduce()

const groceryArray = [
    { id: 'apples', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 },
    { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 },
    { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 },
    { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 },
    { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }
];

groceryArray.sort((a, b) => a.groupDisplayOrder - b.groupDisplayOrder);

const finalOutput = groceryArray.reduce((acc, cur) => {
  if (!acc[cur.groupId]) acc[cur.groupId] = [];
  acc[cur.groupId].push(cur);
  return acc;
}, {});

console.log(finalOutput);

【讨论】:

  • 谢谢!目标是还按 groupDisplayOrder 对新对象键进行排序......例如乳制品应该是第二个键。
  • 谢谢!比我的简单得多:)
【解决方案2】:

您可以采用嵌套方法,使用数组和 groupDisplayOrder,对象以 groupId 作为键。

最后将所有对象组合成一个对象。

const
    groceryArray = [{ id: 'apples', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'chicken', groupId: 'meat', groupDisplayOrder: 3 }, { id: 'shrimp', groupId: 'seafood', groupDisplayOrder: 4 }, { id: 'milk', groupId: 'dairy', groupDisplayOrder: 2 }, { id: 'carrots', groupId: 'produce', groupDisplayOrder: 1 }, { id: 'salmon', groupId: 'seafood', groupDisplayOrder: 4 }],
    result = Object.assign({}, ...groceryArray.reduce((r, o) => {
        ((r[o.groupDisplayOrder] ??= {})[o.groupId] ??= []).push(o);
        return r;
    }, []));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案3】:

    使用MapArray#reduce,您可以对数据进行分组,然后遍历所有值并对它们进行排序。

    const 
      groceryArray=[{id:"apples",groupId:"produce",groupDisplayOrder:1},{id:"chicken",groupId:"meat",groupDisplayOrder:3},{id:"shrimp",groupId:"seafood",groupDisplayOrder:4},{id:"milk",groupId:"dairy",groupDisplayOrder:2},{id:"carrots",groupId:"produce",groupDisplayOrder:1},{id:"salmon",groupId:"seafood",groupDisplayOrder:4}],
    
      res = groceryArray.reduce((r, o) => ((r[o.groupId] ??= []), r[o.groupId].push(o), r), {});
    
    Object.values(res).forEach((o) => o.sort(({ groupDisplayOrder: a }, { groupDisplayOrder: b }) => a - b));
    
    console.log(res);

    【讨论】:

    • @Michael 请检查这是否解决了您的问题,如果您有任何问题,请告诉我。
    猜你喜欢
    • 2020-09-02
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-05
    相关资源
    最近更新 更多