Javascript/Coffeescript Сортировка массива объектов по нескольким ключам, когда значения совпадают

Я пытаюсь отсортировать массив объектов по ключу, но когда значение ключа объекта a совпадает со значением объекта b, следующий ключ будет проверяться до тех пор, пока они окончательно не различаются.

Я пробовал использовать следующий код:

rows.sort (a, b) ->
   for key, value of a
      if a[key] < b[key]
        return -1
      else if a[key] > b[key]
        return 1
      else
        continue

Но это приводит к тому, что массив выглядит по-другому, когда начальный порядок отличается. Любые идеи о том, как этого добиться? Спасибо!

РЕДАКТИРОВАТЬ Массив до:

[ { date: "2013-02-03",
    cpc: 1.46,
    cost: 1.46,
    clicks: 1 },
  { date: "2013-02-05",
    cpc: 1.8375,
    cost: 14.7,
    clicks: 8 },
  { date: "2013-02-06",
    cpc: 1.17,
    cost: 7.02,
    clicks: 6 },
  { date: "2013-02-09",
    cpc: 0.23,
    cost: 0.23,
    clicks: 1 },
  { date: "2013-02-15",
    cpc: 1.4949999999999999,
    cost: 2.9899999999999998,
    clicks: 2 },
  { date: "2013-02-17",
    cpc: 1.21,
    cost: 2.42,
    clicks: 2 },
  { date: "2013-02-18",
    cpc: 1.92,
    cost: 9.6,
    clicks: 5 },
  { date: "2013-02-02",
    cpc: 1.86,
    cost: 1.86,
    clicks: 1 },
  { date: "2013-02-04",
    cpc: 2.35,
    cost: 2.35,
    clicks: 1 },
  { date: "2013-02-11",
    cpc: 1.9625,
    cost: 7.85,
    clicks: 4 },
  { date: "2013-02-16",
    cpc: 2.315,
    cost: 4.63,
    clicks: 2 },
  { date: "2013-02-21",
    cpc: 1.8566666666666667,
    cost: 5.57,
    clicks: 3 },
  { date: "2013-02-22",
    cpc: 1.8375,
    cost: 7.35,
    clicks: 4 },
  { date: "2013-02-25",
    cpc: 1.5066666666666668,
    cost: 4.5200000000000005,
    clicks: 3 },
  { date: "2013-02-26",
    cpc: 2.6,
    cost: 2.6,
    clicks: 1 },
  { date: "2013-02-27",
    cpc: 2.118,
    cost: 10.59,
    clicks: 5 },
  { date: "2013-02-07",
    cpc: 0.2,
    cost: 0.2,
    clicks: 1 },
  { date: "2013-02-08",
    cpc: 1.7850000000000001,
    cost: 7.140000000000001,
    clicks: 4 },
  { date: "2013-02-10",
    cpc: 0.46,
    cost: 0.46,
    clicks: 1 },
  { date: "2013-02-14",
    cpc: 1.955,
    cost: 3.91,
    clicks: 2 },
  { date: "2013-02-19",
    cpc: 1.9233333333333331,
    cost: 17.31,
    clicks: 9 },
  { date: "2013-02-12",
    cpc: 2.39,
    cost: 7.17,
    clicks: 3 },
  { date: "2013-02-13",
    cpc: 2.53,
    cost: 2.53,
    clicks: 1 },
  { date: "2013-02-20",
    cpc: 1.87,
    cost: 1.87,
    clicks: 1 },
  { date: "2013-02-23",
    cpc: 2.265,
    cost: 9.06,
    clicks: 4 },
  { date: "2013-02-28",
    cpc: 2.2425,
    cost: 8.97,
    clicks: 4 },
  { date: "2013-03-01",
    cpc: 1.83,
    cost: 3.66,
    clicks: 2 } ]

И результат после сортировки (вот чего я от него ожидал):

[ { date: '2013-02-02',
    cpc: 1.86,
    cost: 1.86,
    clicks: 1 },
  { date: '2013-02-03',
    cpc: 1.46,
    cost: 1.46,
    clicks: 1 },
  { date: '2013-02-04',
    cpc: 2.35,
    cost: 2.35,
    clicks: 1 },
  { date: '2013-02-05',
    cpc: 1.8375,
    cost: 14.7,
    clicks: 8 },
  { date: '2013-02-06',
    cpc: 1.17,
    cost: 7.02,
    clicks: 6 },
  { date: '2013-02-07',
    cpc: 0.2,
    cost: 0.2,
    clicks: 1 },
  { date: '2013-02-08',
    cpc: 1.7850000000000001,
    cost: 7.140000000000001,
    clicks: 4 },
  { date: '2013-02-09',
    cpc: 0.23,
    cost: 0.23,
    clicks: 1 },
  { date: '2013-02-10',
    cpc: 0.46,
    cost: 0.46,
    clicks: 1 },
  { date: '2013-02-11',
    cpc: 1.9625,
    cost: 7.85,
    clicks: 4 },
  { date: '2013-02-12',
    cpc: 2.39,
    cost: 7.17,
    clicks: 3 },
  { date: '2013-02-13',
    cpc: 2.53,
    cost: 2.53,
    clicks: 1 },
  { date: '2013-02-14',
    cpc: 1.955,
    cost: 3.91,
    clicks: 2 },
  { date: '2013-02-15',
    cpc: 1.4949999999999999,
    cost: 2.9899999999999998,
    clicks: 2 },
  { date: '2013-02-16',
    cpc: 2.315,
    cost: 4.63,
    clicks: 2 },
  { date: '2013-02-17',
    cpc: 1.21,
    cost: 2.42,
    clicks: 2 },
  { date: '2013-02-18',
    cpc: 1.92,
    cost: 9.6,
    clicks: 5 },
  { date: '2013-02-19',
    cpc: 1.9233333333333331,
    cost: 17.31,
    clicks: 9 },
  { date: '2013-02-20',
    cpc: 1.87,
    cost: 1.87,
    clicks: 1 },
  { date: '2013-02-21',
    cpc: 1.8566666666666667,
    cost: 5.57,
    clicks: 3 },
  { date: '2013-02-22',
    cpc: 1.8375,
    cost: 7.35,
    clicks: 4 },
  { date: '2013-02-23',
    cpc: 2.265,
    cost: 9.06,
    clicks: 4 },
  { date: '2013-02-25',
    cpc: 1.5066666666666668,
    cost: 4.5200000000000005,
    clicks: 3 },
  { date: '2013-02-26',
    cpc: 2.6,
    cost: 2.6,
    clicks: 1 },
  { date: '2013-02-27',
    cpc: 2.118,
    cost: 10.59,
    clicks: 5 },
  { date: '2013-02-28',
    cpc: 2.2425,
    cost: 8.97,
    clicks: 4 },
  { date: '2013-03-01',
    cpc: 1.83,
    cost: 3.66,
    clicks: 2 } ]

Когда вы заказываете, начальный массив:

[ { date: '2013-02-02',
    cpc: 1.86,
    cost: 1.86,
    clicks: 1 },
  { date: '2013-02-04',
    cpc: 2.35,
    cost: 2.35,
    clicks: 1 },
  { date: '2013-02-05',
    cpc: 1.8375,
    cost: 14.7,
    clicks: 8 },
  { date: '2013-02-06',
    cpc: 1.17,
    cost: 7.02,
    clicks: 6 },
  { date: '2013-02-11',
    cpc: 1.9625,
    cost: 7.85,
    clicks: 4 },
  { date: '2013-02-12',
    cpc: 2.39,
    cost: 7.17,
    clicks: 3 },
  { date: '2013-02-16',
    cpc: 2.315,
    cost: 4.63,
    clicks: 2 },
  { date: '2013-02-18',
    cpc: 1.92,
    cost: 9.6,
    clicks: 5 },
  { date: '2013-02-20',
    cpc: 1.87,
    cost: 1.87,
    clicks: 1 },
  { date: '2013-02-21',
    cpc: 1.8566666666666667,
    cost: 5.57,
    clicks: 3 },
  { date: '2013-02-28',
    cpc: 2.2425,
    cost: 8.97,
    clicks: 4 },
  { date: '2013-03-01',
    cpc: 1.83,
    cost: 3.66,
    clicks: 2 },
  { date: '2013-02-03',
    cpc: 1.46,
    cost: 1.46,
    clicks: 1 },
  { date: '2013-02-07',
    cpc: 0.2,
    cost: 0.2,
    clicks: 1 },
  { date: '2013-02-09',
    cpc: 0.23,
    cost: 0.23,
    clicks: 1 },
  { date: '2013-02-10',
    cpc: 0.46,
    cost: 0.46,
    clicks: 1 },
  { date: '2013-02-17',
    cpc: 1.21,
    cost: 2.42,
    clicks: 2 },
  { date: '2013-02-19',
    cpc: 1.9233333333333331,
    cost: 17.31,
    clicks: 9 },
  { date: '2013-02-25',
    cpc: 1.5066666666666668,
    cost: 4.5200000000000005,
    clicks: 3 },
  { date: '2013-02-08',
    cpc: 1.7850000000000001,
    cost: 7.140000000000001,
    clicks: 4 },
  { date: '2013-02-13',
    cpc: 2.53,
    cost: 2.53,
    clicks: 1 },
  { date: '2013-02-14',
    cpc: 1.955,
    cost: 3.91,
    clicks: 2 },
  { date: '2013-02-15',
    cpc: 1.4949999999999999,
    cost: 2.9899999999999998,
    clicks: 2 },
  { date: '2013-02-22',
    cpc: 1.8375,
    cost: 7.35,
    clicks: 4 },
  { date: '2013-02-23',
    cpc: 2.265,
    cost: 9.06,
    clicks: 4 },
  { date: '2013-02-26',
    cpc: 2.6,
    cost: 2.6,
    clicks: 1 },
  { date: '2013-02-27',
    cpc: 2.118,
    cost: 10.59,
    clicks: 5 }]

Результат сортировки массивом hussled:

[ { date: '2013-02-02',
    cpc: 1.86,
    cost: 1.86,
    clicks: 1 },
  { date: '2013-02-03',
    cpc: 1.46,
    cost: 1.46,
    clicks: 1 },
  { date: '2013-02-04',
    cpc: 2.35,
    cost: 2.35,
    clicks: 1 },
  { date: '2013-02-05',
    cpc: 1.8375,
    cost: 14.7,
    clicks: 8 },
  { date: '2013-02-06',
    cpc: 1.17,
    cost: 7.02,
    clicks: 6 },
  { date: '2013-02-07',
    cpc: 0.2,
    cost: 0.2,
    clicks: 1 },
  { date: '2013-02-08',
    cpc: 1.7850000000000001,
    cost: 7.140000000000001,
    clicks: 4 },
  { date: '2013-02-10',
    cpc: 0.46,
    cost: 0.46,
    clicks: 1 },
  { date: '2013-02-11',
    cpc: 1.9625,
    cost: 7.85,
    clicks: 4 },
  { date: '2013-02-12',
    cpc: 2.39,
    cost: 7.17,
    clicks: 3 },
  { date: '2013-02-13',
    cpc: 2.53,
    cost: 2.53,
    clicks: 1 },
  { date: '2013-02-14',
    cpc: 1.955,
    cost: 3.91,
    clicks: 2 },
  { date: '2013-02-15',
    cpc: 1.4949999999999999,
    cost: 2.9899999999999998,
    clicks: 2 },
  { date: '2013-02-16',
    cpc: 2.315,
    cost: 4.63,
    clicks: 2 },
  { date: '2013-02-17',
    cpc: 1.21,
    cost: 2.42,
    clicks: 2 },
  { date: '2013-02-18',
    cpc: 1.92,
    cost: 9.6,
    clicks: 5 },
  { date: '2013-02-19',
    cpc: 1.9233333333333331,
    cost: 17.31,
    clicks: 9 },
  { date: '2013-02-20',
    cpc: 1.87,
    cost: 1.87,
    clicks: 1 },
  { date: '2013-02-21',
    cpc: 1.8566666666666667,
    cost: 5.57,
    clicks: 3 },
  { date: '2013-02-22',
    cpc: 1.8375,
    cost: 7.35,
    clicks: 4 },
  { date: '2013-02-23',
    cpc: 2.265,
    cost: 9.06,
    clicks: 4 },
  { date: '2013-02-09',
    cpc: 0.23,
    cost: 0.23,
    clicks: 1 },
  { date: '2013-02-25',
    cpc: 1.5066666666666668,
    cost: 4.5200000000000005,
    clicks: 3 },
  { date: '2013-02-26',
    cpc: 2.6,
    cost: 2.6,
    clicks: 1 },
  { date: '2013-02-27',
    cpc: 2.118,
    cost: 10.59,
    clicks: 5 },
  { date: '2013-02-28',
    cpc: 2.2425,
    cost: 8.97,
    clicks: 4 },
  { date: '2013-03-01',
    cpc: 1.83,
    cost: 3.66,
    clicks: 2 } ]

person Nyveria    schedule 15.04.2015    source источник
comment
Спасибо за ваш комментарий, добавленный для уточнения. Я ожидаю, что первый пример отсортированного массива будет тем, что выкатывается каждый раз.   -  person Nyveria    schedule 15.04.2015
comment
На самом деле, не имеет значения, какой именно, если он ВСЕГДА возвращает один и тот же порядок.   -  person Nyveria    schedule 16.04.2015


Ответы (2)


Вам не нужен continue. И не забудьте вернуть 0, когда объекты совпадают:

rows.sort (a, b) ->
  for key, value of a
    if a[key] < b[key]
      return -1
    else if a[key] > b[key]
      return 1

  return 0

Большая проблема - ключи объектов не отсортированы. Нет никаких оснований ожидать, что каждый раз в цикле for первый ключ будет датой, второй — ценой за клик и т. д. Вы действительно хотите иметь предопределенный массив ключей по порядку и использовать его, а не просто получение списка ключей от объектов

keys = ["a","b","c"]

rows.sort (a, b) ->
  for key in keys
    if a[key] < b[key]
      return -1
    else if a[key] > b[key]
     return 1

  return 0

Пример

person Paul Roub    schedule 15.04.2015
comment
О вау. Прежде всего, спасибо за быстрый ответ! Я был так сосредоточен на следующем ключе, что даже не подумал об этом. Так очевидно. Большое спасибо! Тем не менее, делая это, я все равно получаю другой порядок, когда порядок исходного массива отличается. - person Nyveria; 15.04.2015
comment
Затем вам нужно опубликовать пример массива, который показывает проблему (в вопросе, а не в комментарии, для достижения наилучших результатов). - person Paul Roub; 15.04.2015
comment
Да, извините, добавил! ;) (раньше не добавлял, потому что они очень длинные) - person Nyveria; 15.04.2015
comment
Большая проблема - ключи объектов не отсортированы. Нет причин ожидать, что каждый раз в цикле for первый key будет date, второй будет cpc и т. д. Вы действительно хотите иметь предопределенный массив ключей по порядку и использовать его, а не просто получение списка key из объектов. - person Paul Roub; 15.04.2015
comment
@muistooshort Хороший вопрос. Переместил его с кодом в ответ. - person Paul Roub; 15.04.2015
comment
Хороший вопрос, хотя я не знаю заранее, с какими ключами мне придется иметь дело. В этом случае это будет работать, но если пользователь запрашивает больше, чем эти ключи, или что-то совершенно другое, это больше не будет работать. - person Nyveria; 15.04.2015
comment
Затем используйте ключи, которые запрашивает пользователь. Дело в том, что вы не можете рассчитывать на то, что ключи, исходящие от объекта, будут в удобном порядке. - person Paul Roub; 15.04.2015
comment
@PaulRoub Спасибо, думаю, тогда я так и сделаю. Вы также не можете рассчитывать на то, что они будут в одном и том же порядке каждый раз, но в моем случае те, что указаны в запросе, намного надежнее. ;) - person Nyveria; 16.04.2015

Я собирался задать этот вопрос, но обнаружил, что был похожий вопрос, оказалось, что ответ был чем-то, что я уже делал, но у этого был цикл FOR IN. Я проверил это, и это не дало мне того, что я хотел. Затем я решил заменить цикл for на немного больше кода, когда значения одинаковы. Вот результаты

Перебираем заданные ключи и сравниваем все

Результат цикла

Сравнение другой пары

Результат

person Possible    schedule 02.09.2020