【问题标题】:How to sort an array with dynamic property? [duplicate]如何对具有动态属性的数组进行排序? [复制]
【发布时间】:2019-04-06 07:27:29
【问题描述】:

我有一组电影,我试图根据标记为“路径”的动态值进行排序,该值根据当前的情况评估为“标题”、“流派名称”、“编号InStock”或“每日租借率”状态。然而,因为电影数组中的“流派”属性是一个对象,而不是像其他的字符串,所以我编写的比较函数试图访问movieA(“genre.name”)和movieB(“genre.name”)。我认为这种语法可能有效,但它没有。当然,必须有一种优雅的方式来编写我的比较函数,而不需要在路径设置为“genre.name”时添加更多条件?非常感谢任何帮助或见解。谢谢。(下面是一些代码 sn-ps)

var movies = [
    {
        title: "Terminator",
        genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
        numberInStock: 6,
        dailyRentalRate: 2.5,
    },
    {
        title: "Die Hard",
        genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
        numberInStock: 5,
        dailyRentalRate: 2.5
    },
    {
        title: "Get Out",
        genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
        numberInStock: 8,
        dailyRentalRate: 3.5
    }
]

this.state = {
    path: "title"  //'title' or 'genre.name' or 'numberInStock' or 'dailyRentalRate'
};

myCompare = (a, b) => {
    const path  = this.state.path;

    if (a[path] < b[path]) return - 1;
    if (a[path] > b[path]) return 1;
    return 0;
}

const moviesSorted = movies.sort(this.myCompare);

【问题讨论】:

    标签: javascript arrays reactjs sorting properties


    【解决方案1】:

    当路径包含句点时,您应该将其转换为带有split 的数组,然后使用reduce 对其进行迭代并找到您尝试排序的嵌套值:

    var movies = [
        {
            title: "foo bar",
            genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
            numberInStock: 8,
            dailyRentalRate: 3
        },
        {
            title: "Terminator",
            genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
            numberInStock: 6,
            dailyRentalRate: 2.5,
        },
        {
            title: "Die Hard",
            genre: { _id: "5b21ca3eeb7f6fbccd471818", name: "Action" },
            numberInStock: 5,
            dailyRentalRate: 2
        },
        {
            title: "Get Out",
            genre: { _id: "5b21ca3eeb7f6fbccd471820", name: "Thriller" },
            numberInStock: 8,
            dailyRentalRate: 3.5
        }
    ];
    
    let path = "title";
    
    const getNested = (obj, path) => path.split('.').reduce((a, prop) => a[prop], obj);
    const myCompare = (a, b) => {
      const aVal = getNested(a, path);
      return typeof aVal === 'string'
      ? aVal.localeCompare(getNested(b, path))
      : aVal - getNested(b, path);
    };
    
    // Sort by title:
    movies.sort(myCompare);
    console.log(movies);
    
    // Sort by genre.name:
    path = 'genre.name';
    movies.sort(myCompare);
    console.log(movies);

    【讨论】:

      【解决方案2】:

      或许,您可以编写一个辅助函数来获取嵌套值,如下所示:

      function getNestedValue(fieldName, item) {
          if (fieldName.includes('.')) {
              const keyArr = fieldName.split('.');
              let result = item;
              if (keyArr.length > 1) {
                  for (const key of keyArr) {
                      result = result[key];
                  }
      
                  return result;
              }
          }
      
          return item[fieldName];
      }
      
      myCompare = (a, b) => {
          const { path } = this.state.sortColumn;
          const valueA = getNestedValue(path, a);
          const valueB = getNestedValue(path, b)
      
          if (valueA < valueB) return - 1;
          if valueA > valueB) return 1;
          return 0;
      }
      

      并比较给定的结果。

      【讨论】:

        猜你喜欢
        • 2020-12-20
        • 1970-01-01
        • 2018-07-05
        • 2021-09-05
        • 1970-01-01
        • 2019-10-01
        • 1970-01-01
        • 2020-05-15
        • 2013-05-25
        相关资源
        最近更新 更多