Как отсортировать массив с помощью coffeescript? - PullRequest
19 голосов
/ 21 марта 2012

с таким массивом:

users = [ 
   { id: 1, fname: 'Fred', lname: 'Flinstone', state: 'CA' }, 
   { id: 2, fname: 'George', lname: 'Winston', state: 'FL' },
   { id: 3, fname: 'Luke', lname: 'Skywalker', state: 'CA' }
]

и вы хотите отсортировать по фамилии с помощью coffeescript, вы можете сделать это:

users.sort (a,b) ->
  return if a.lname.toUpperCase() >= b.lname.toUpperCase() then 1 else -1

Я пытался использовать такую ​​функцию, как эта:

sortBy = (field, reverse, primer) ->
    key = (x) ->
      return if primer? then primer x[field] else x[field]
    return (a,b) ->
      A = key a
      B = key b
      return (A < B ? -1 : (A > B ? 1 : 0)) * [1,-1][+!!reverse]

, который был вызван следующим образом:

users.sort sortBy "lname", false, (a) -> 
  return a.toUpperCase()

, но не отсортировал массив должным образом.

Есть ли способ сортировки более чем на1 поле, т.е. сортировка сначала по Штату, а затем по Фамилии?Я надеялся улучшить описанную выше функцию «sortBy» и добавить возможность сортировки по крайней мере на 2 поля.

Ответы [ 3 ]

20 голосов
/ 21 марта 2012

Есть более простой способ. Просто повторно используйте вашу обобщенную функцию сортировки и объедините их, используя ||:

sortBy = (key, a, b, r) ->
    r = if r then 1 else -1
    return -1*r if a[key] > b[key]
    return +1*r if a[key] < b[key]
    return 0

users.sort (a,b) ->
    sortBy('id', a, b, true) or
    sortBy('lname', a, b) or
    sortBy('fname', a, b)

Функции дешевы. Затем вы можете построить для этого абстракцию:

sortByMultiple = (a, b, keys) ->
    return r if (r = sortBy key, a, b) for key in keys
    return 0

users.sort (a,b) -> sortByMultiple a, b, ['id', 'lname', 'fname']

Но тогда вы теряете возможность устанавливать порядок или другие параметры для каждого из них.

16 голосов
/ 21 марта 2012

В качестве альтернативы вы можете рассмотреть возможность использования Underscore s sortBy , чтобы вам не пришлось реализовывать его самостоятельно:

_(users).sortBy (u) -> [u.state, u.lname.toUpperCase()]
3 голосов
/ 11 ноября 2015

Я подумал, что это было бы реализовано по умолчанию при использовании lodash , но это не так.

Итак, мы здесь!

sortByLowercase: (collection, key) ->
    collection.sort (a, b) ->
      [av, bv] = [a[key], b[key]]
      [av, bv] = [av.toLowerCase(), bv.toLowerCase()]
      if av >= bv then 1 else if av <= bv then -1 else 0

sortByLowercase(users,'lname')

На основе более общего примера, который я нашел здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...