如何使用自定义顺序对组进行排序?

问题描述 投票:0回答:1

目前发送回客户端的响应如下所示:

[
  {
    "categoryName": "Orders",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Notifications",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Personalisation",
    "categorySettings": ...the rest
  }
]

但是,预期的布局是:

[
  {
    "categoryName": "Personalisation",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Notifications",
    "categorySettings": ...the rest
  },
  {
    "categoryName": "Orders",
    "categorySettings": ...the rest
  }
]

如何对

categoryName
进行排序以符合我预期的顺序?我正在考虑将排序顺序与具有
categoryName
sequence
的对象数组相匹配 属性,但我被代码困住了。

我当前的代码如下:

const groupedData = _.chain(allData)
      .groupBy('sectionName')
      .map((allData, sectionName) => ({
        categoryName: sectionName,
        categorySettings: _.chain(allData)
          .groupBy('group')
          .map((groupSettings, group) => ({
            group: group,
            groupSettings: _.chain(groupSettings)
              .sortBy('ordering')
              .groupBy('title')
              .map((titleSettings, title) => ({
                settingName: title,
                settingDescription: titleSettings[0].description,
                settingInputs: _.map(titleSettings, ({name, value, inputSetting}) => ({
                  inputName: name,
                  inputValue: value,
                  inputConfig: inputSetting,
                })),
              }))
              .value(),
          }))
          .value(),
      }))
      .value();
javascript lodash
1个回答
0
投票

您可以创建一个具有预期顺序的数组,并使用它根据类别名称对 groupedData 数组进行排序

const sortOrder = [
  { categoryName: "Personalisation", sequence: 1 },
  { categoryName: "Notifications", sequence: 2 },
  { categoryName: "Orders", sequence: 3 }
];

const sortedGroupedData = _.chain(allData)
  ... // your function
  .value();

最后对数组进行排序

const finalSortedData = _.sortBy(sortedGroupedData, (item) => {
  const order = sortOrder.find(o => o.categoryName === item.categoryName);
  return order ? order.sequence : Infinity; // Infinity will make sure that any category not in sortOrder will be at the end
});
console.log(finalSortedData);

(或)更类型安全的解决方案

您可以创建

categoryName
到所需顺序(即索引)的映射,然后使用该映射对数据进行排序。

我重用了你的代码。考虑到你正在使用 TS,我也将其设置为类型安全的:

//define an enum for checking during compile time
enum CategoryName {
  Personalisation = "Personalisation",
  Notifications = "Notifications",
  Orders = "Orders",
}

//this creates a mapping of categoryName to its index in enum order
const orderMap: Record<CategoryName, number> = {
  [CategoryName.Personalisation]: 0,
  [CategoryName.Notifications]: 1,
  [CategoryName.Orders]: 2,
};

const sortedGroupedData = _.chain(allData)
  .groupBy('sectionName')
  .map((allData, sectionName) => ({
    categoryName: sectionName as CategoryName, // typing sectionName as CategoryName
    categorySettings: _.chain(allData)
      .groupBy('group')
      .map((groupSettings, group) => ({
        group: group,
        groupSettings: _.chain(groupSettings)
          .sortBy('ordering')
          .groupBy('title')
          .map((titleSettings, title) => ({
            settingName: title,
            settingDescription: titleSettings[0].description,
            settingInputs: _.map(titleSettings, ({ name, value, inputSetting }) => ({
              inputName: name,
              inputValue: value,
              inputConfig: inputSetting,
            })),
          }))
          .value(),
      }))
      .value(),
  }))
  .sortBy(item => orderMap[item.categoryName]) //sorting here
  .value();

console.log(sortedGroupedData);

您可以使用更适合您的任何一个(显然要确保类型安全)

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.