Сортировка массива в рубине - PullRequest
0 голосов
/ 23 декабря 2009

Пользователь определил порядок столбцов в массиве.

order = [:col1, :col2, :col3]

Поскольку пользовательский порядок столбцов изменился, состояние таблицы изменилось, и текущий список столбцов равен

cols = [:col1, :col4, :col3, :col5]

С заданным порядком cols нужно отсортировать. В этом случае отсортированные столбцы могут выглядеть как один из этих двух случаев.

[:col2, :col3, :col4, :col5] 
[:col2, :col3, :col5, :col4]

Вот мой код, чтобы заставить его работать. Хотите знать, если есть лучший способ.

#get rid of :col2 since it is not present in the cols listing
sanitized_order = order - (order - cols)

sorted_cols = sanitized_order + (cols - sanitized_order)

Ответы [ 2 ]

2 голосов
/ 23 декабря 2009

Что вы подразумеваете под лучше? Вы уже выполнили свою задачу довольно легко.

1) Это как ваша, но 1 читаемая строка.

#order & cols -> provides unique items found in both
#cols - order -> provides columns that are in cols but not order
sorted_cols = (order & cols) + (cols - order)

2) Вот способ, который читается больше как книга, так что кто-то мог бы следовать за ней построчно, чтобы увидеть логику, а не выяснять различия в таблицах:

order = [:col1, :col2, :col3]
cols = [:col1, :col4, :col3, :col5]

sanitized_order = []

order.each do |column|
  if cols.include?(column) then
    sanitized_order << column
    cols.delete(column)
  end
end

cols.each do |remainingcolumn|
  sanitized_order << remainingcolumn
end

puts sanitized_order
0 голосов
/ 26 декабря 2009

Вот еще один многословный способ сделать это:

order = [:col1, :col2, :col3]
cols = [:col3, :col2, :col5, :col4]
sorted_order = cols.sort_by do |c|
  if order.index(c)
    [1, order.index(c)]
  else
    [2, cols.index(c)]
  end
end
p sorted_order    # => [:col2, :col3, :col5, :col4]

Вот как это работает. sort_by возвращает элементы массива в блок; блок должен затем возвращать что-то сопоставимое (технически то, что отвечает оператору <=>). sort_by использует оператор <=> для результатов, возвращаемых блоком, чтобы решить, в каком порядке должен быть массив.

Оператор <=> (космический корабль), как вы, возможно, знаете, является двоичным оператором, принимающим два элемента a и b. Если a b, возвращается + 1.

Массивы не удивительно отвечают оператору <=>. Элементы левого массива сравниваются с элементами правого массива по очереди, начиная с индекса 0 и увеличиваясь. Если a [i] <=> b [i] равно! = 0, верните этот результат, но если результат равен 0, проверьте следующий элемент. Если последняя пара сравниваемых элементов равна 0 (равно), а массивы имеют одинаковый размер, массивы равны, и Array. <=> Возвращает 0, в противном случае более длинный массив считается большим (однако в этом примере всегда возвращаются массивы одинакового размера, однако ).

Так, например:

[2, 1] <=> [2, 2] == -1
[2, 2] <=> [2, 2] == 0
[2, 3] <=> [2, 2] == +1
[1, 2] <=> [2, 1] == +1

Итак, внутри sort_by мы можем использовать элементы массива a для указания первичного, вторичного, третичного и т. Д. Порядка сортировки. [0] - это первичный порядок сортировки, a [1] - это вторичный порядок сортировки и т. д.

Все столбцы, указанные клиентом, должны стоять на первом месте. Поэтому для каждого столбца найдите его индекс в указанном заказчиком порядке (order). Если это возвращает число, то мы знаем, что клиент указал этот столбец, и мы знаем его индекс в указанном клиентом списке. Основной порядок сортировки - 1, потому что мы хотим, чтобы указанные пользователем столбцы были первыми; вторичный порядок сортировки - это индекс, поскольку он дает нам заказ, указанный клиентом в столбцах.

Если мы не найдем столбец в массиве order (то есть, order.index (c) возвращает nil), тогда мы будем использовать 2 в качестве основного порядка сортировки и индекс в списке главного столбца (cols) как вторичный порядок сортировки. Таким образом, все столбцы, которые клиент не указал, будут последними, но в порядке, указанном в списке последних столбцов.

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