从这个最初的问题,我将如何在多个字段应用排序?

使用这种稍作调整的结构,我将如何排序城市(上升)和价格(下降)?

var homes = [
    {"h_id":"3",
     "city":"Dallas",
     "state":"TX",
     "zip":"75201",
     "price":"162500"},
    {"h_id":"4",
     "city":"Bevery Hills",
     "state":"CA",
     "zip":"90210",
     "price":"319250"},
    {"h_id":"6",
     "city":"Dallas",
     "state":"TX",
     "zip":"75000",
     "price":"556699"},
    {"h_id":"5",
     "city":"New York",
     "state":"NY",
     "zip":"00010",
     "price":"962500"}
    ];

我喜欢的事实是,给出的答案提供了一个一般的方法。在我计划使用这段代码的地方,我将不得不对日期以及其他东西进行排序。“启动”对象的能力似乎很方便,如果不是有点麻烦的话。

我试图把这个答案构建成一个很好的通用示例,但我运气不太好。


当前回答

在这里,您可以尝试按多个字段进行排序的更小且方便的方法!

var homes = [ { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "6", "city": "Dallas", "state": "TX", "zip": "75000", "price": "556699" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" } ]; homes.sort((a, b)=> { if (a.city === b.city){ return a.price < b.price ? -1 : 1 } else { return a.city < b.city ? -1 : 1 } }) console.log(homes);

其他回答

按多个字段排序对象数组的最简单方法:

 let homes = [ {"h_id":"3",
   "city":"Dallas",
   "state":"TX",
   "zip":"75201",
   "price":"162500"},
  {"h_id":"4",
   "city":"Bevery Hills",
   "state":"CA",
   "zip":"90210",
   "price":"319250"},
  {"h_id":"6",
   "city":"Dallas",
   "state":"TX",
   "zip":"75000",
   "price":"556699"},
  {"h_id":"5",
   "city":"New York",
   "state":"NY",
   "zip":"00010",
   "price":"962500"}
  ];

homes.sort((a, b) => (a.city > b.city) ? 1 : -1);

输出: “Bevery山” “达拉斯” “达拉斯” “达拉斯” “纽约”

在这里,您可以尝试按多个字段进行排序的更小且方便的方法!

var homes = [ { "h_id": "3", "city": "Dallas", "state": "TX", "zip": "75201", "price": "162500" }, { "h_id": "4", "city": "Bevery Hills", "state": "CA", "zip": "90210", "price": "319250" }, { "h_id": "6", "city": "Dallas", "state": "TX", "zip": "75000", "price": "556699" }, { "h_id": "5", "city": "New York", "state": "NY", "zip": "00010", "price": "962500" } ]; homes.sort((a, b)=> { if (a.city === b.city){ return a.price < b.price ? -1 : 1 } else { return a.city < b.city ? -1 : 1 } }) console.log(homes);

今天我做了一个相当通用的多特征排序器。你可以在这里看看byjs: https://github.com/Teun/thenBy.js

它允许您使用标准数组。排序,但使用firstBy(). thenby (). thenby()样式。它比上面发布的解决方案少了很多代码和复杂性。

通过添加两个辅助函数,可以简单地解决这类问题。sortByKey接受一个数组和一个函数,该函数应返回一个项目列表,用于与每个数组条目进行比较。

这利用了javascript对简单值的数组进行智能比较的事实,即[2]<[2,0]<[2,1]<[10,0]。

// Two helpers: function cmp(a, b) { if (a > b) { return 1 } else if (a < b) { return -1 } else { return 0 } } function sortByKey(arr, key) { arr.sort((a, b) => cmp(key(a), key(b))) } // A demonstration: let arr = [{a:1, b:2}, {b:3, a:0}, {a:1, b:1}, {a:2, b:2}, {a:2, b:1}, {a:1, b:10}] sortByKey(arr, item => [item.a, item.b]) console.log(JSON.stringify(arr)) // '[{"b":3,"a":0},{"a":1,"b":1},{"a":1,"b":10},{"a":1,"b":2},{"a":2,"b":1},{"a":2,"b":2}]' sortByKey(arr, item => [item.b, item.a]) console.log(JSON.stringify(arr)) // '[{"a":1,"b":1},{"a":2,"b":1},{"a":1,"b":10},{"a":1,"b":2},{"a":2,"b":2},{"b":3,"a":0}]'

我从Python的列表中偷取了这个想法。排序功能。

这是一个通用的多维排序,允许在每个层次上进行反转和/或映射。

用Typescript编写。对于Javascript,请查看这个JSFiddle

的代码

type itemMap = (n: any) => any;

interface SortConfig<T> {
  key: keyof T;
  reverse?: boolean;
  map?: itemMap;
}

export function byObjectValues<T extends object>(keys: ((keyof T) | SortConfig<T>)[]): (a: T, b: T) => 0 | 1 | -1 {
  return function(a: T, b: T) {
    const firstKey: keyof T | SortConfig<T> = keys[0];
    const isSimple = typeof firstKey === 'string';
    const key: keyof T = isSimple ? (firstKey as keyof T) : (firstKey as SortConfig<T>).key;
    const reverse: boolean = isSimple ? false : !!(firstKey as SortConfig<T>).reverse;
    const map: itemMap | null = isSimple ? null : (firstKey as SortConfig<T>).map || null;

    const valA = map ? map(a[key]) : a[key];
    const valB = map ? map(b[key]) : b[key];
    if (valA === valB) {
      if (keys.length === 1) {
        return 0;
      }
      return byObjectValues<T>(keys.slice(1))(a, b);
    }
    if (reverse) {
      return valA > valB ? -1 : 1;
    }
    return valA > valB ? 1 : -1;
  };
}

用法示例

先按姓排序,再按名排序:

interface Person {
  firstName: string;
  lastName: string;
}

people.sort(byObjectValues<Person>(['lastName','firstName']));

按语言代码的名称排序,而不是按语言代码排序(见地图),然后按降序排序(见反向)。

interface Language {
  code: string;
  version: number;
}

// languageCodeToName(code) is defined elsewhere in code

languageCodes.sort(byObjectValues<Language>([
  {
    key: 'code',
    map(code:string) => languageCodeToName(code),
  },
  {
    key: 'version',
    reverse: true,
  }
]));