【问题标题】:Sort an Array of Objects based on key, and based on value根据键和值对对象数组进行排序
【发布时间】:2017-09-29 09:05:38
【问题描述】:

考虑一下:

[{name:'John'},{age:25},{address:'some street'}]

正如你所见,没有一个键是一致的名称,所以我不能使用。

arr.sort((a,b)=> a.consistentKey < b.consistentKey);

如何按名称和值对此类内容进行排序?

所以以下按字母顺序按键排序应该是:

[{address:'some street'},{age:25},{name:'John'}]

【问题讨论】:

  • 能解释一下你想如何排序吗?
  • 鉴于对象没有一致的属性名称或类型,它们没有可比性,我想知道您到底想如何对它们进行排序。
  • @Kind user 考虑整个对象,它会有什么不同?...我正在向数组中添加随机键值对,但想根据键或值对它们进行排序...这怎么可能?
  • 整个任务对我来说没有意义。您要构建什么?
  • @Thomas 没有冒犯,但如果你不能帮助我完成这部分。我怀疑你能帮助我完成整个项目。

标签: javascript arrays sorting object


【解决方案1】:

以下是我将使用的解决方案。此解决方案提供 keys only 排序、values only 排序、keys then values 排序和 values then keys em> 排序。

class FunkySort {
  sort (sortType) {
    switch (sortType) {
      case 'keysOnly':
        return data => this._sortByKey(data);
      case 'valuesOnly':
        return data => this._sortByValue(data);
      case 'valuesPrimary':
        return data => {
          data = this._sortByKey(data);
          return this._sortByValue(data);
        };
      case 'keysPrimary':
        return data => {
          data = this._sortByValue(data);
          return this._sortByKey(data);
        };
    }
  }

  _sortByKey (data) {
    return data.sort((a, b) => {
      var keyA = Object.keys(a)[0];
      var keyB = Object.keys(b)[0];
      return keyA < keyB ? -1 : keyA > keyB ? 1 : 0;
    });
  }

  _sortByValue (data) {
    return data.sort((a, b) => {
      // note that in Node >=v7 you could use `Object.values()`, but not in <v7.0
      var valueA = a[Object.keys(a)[0]];
      var valueB = b[Object.keys(b)[0]];
      return valueA < valueB ? -1 : valueA > valueB ? 1 : 0;
    });
  }
}

const dataArr = [{name:'John'},{age:25},{address:'some street'}];
const fs = new FunkySort();
fs.sort('keysPrimary')(dataArr);

注意fs.sort 是一个柯里化函数。第一次调用设置要完成的排序类型,因此fs.sort('keysPrimary') 返回一个函数,该函数接受一个对象数组并首先按值排序,然后按键排序,从而产生一个按键排序的对象数组,并且如果有多个对象具有相同的键,则按值排序。

如果您在排序类型方面不需要这种级别的灵活性,那么只需 _sortByKey 辅助方法就足够了。

【讨论】:

    【解决方案2】:

    你可以这样做

    input.sort((a, b) => {
      const keya = Object.keys(a)[0];
      const keyb = Object.keys(b)[0];
    
      return keya.localeCompare(keyb) || a[keya].localeCompare(b[keyb]);
    });
    

    在面对不同的语言环境时,使用localeCompare 既短又健壮。

    【讨论】:

      【解决方案3】:

      如果您想先按键排序,然后再按值排序,您可以尝试以下方法:

      var a = [{name:'John'},{age:25},{address:'some street'}];
              
          alert(JSON.stringify(a.sort((a, b) => {
            nameA = Object.keys(a)[0];
            nameB = Object.keys(b)[0];
          
            if (nameA < nameB) {
              return -1;
            }
            if (nameA > nameB) {
              return 1;
            }
          
            // names must be equal
            return 0;
          })));

      这里我只考虑了一个键,但您始终可以将其扩展到多个键,同样您也可以根据值进一步排序。

      【讨论】:

      • 你介意控制台。记录答案? alert 只显示 [object object]
      • 即使控制台也会打印除 chrome 之外的对象对象。我已经对调试内容进行了字符串化。底线是这段代码应该可以工作。
      • console.dir(someObject) 将让您在控制台中解压对象内容
      【解决方案4】:

      如果您使用Object.keys 提取键名,那么您可以获得执行比较所需的值:

      [{name: 'John'}, {age: 25}, {address:'some street'}].sort((a, b) => {
        const keyA = Object.keys(a)[0]
        const valA = a[keyA]
        const keyB = Object.keys(b)[0]
        const valB = a[keyB]
      
        if (keyA > keyB) {
          return 1
        } else if (keyA < keyB) {
          return -1
        } else /* equal */ {
         if (valA > valB) {
            return 1
          } else if (valA < valB) {
            return -1
          } else /* equal */ {
            return 0
          }
        }
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-11-25
        • 2013-05-14
        • 1970-01-01
        • 2018-12-27
        • 1970-01-01
        • 2011-04-05
        • 2021-04-26
        • 1970-01-01
        相关资源
        最近更新 更多