Сортировка массива хэшей с наименьшим значением в середине - PullRequest
0 голосов
/ 22 сентября 2019

Я новичок в ruby ​​и не смог найти ответа или логики о том, как я могу это сделать.Я пытаюсь разделить массив пополам, а половину отсортировать по убыванию, а другую половину - по возрастанию.

Короче говоря, давайте рассмотрим, есть ли у нас следующий массив хэшей:

[
 {:rating=>1, :num=>1},
 {:rating=>1, :num=>1},
 {:rating=>3.5, :num=>37},
 {:rating=>4.0, :num=>23},
 {:rating=>4.0, :num=>72},
 {:rating=>4.0, :num=>38}, 
 {:rating=>3.5, :num=>72}, 
 {:rating=>4.0, :num=>74}
]

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

Сначала мне нужно получить хеш с наименьшим ключом :ratingзначение и :num значение ключа и вставьте его в новый массив.Остальные хэши должны быть отсортированы asc после :rating и :num, а затем каждый из хэшей, начиная с того, который имеет наименьшее значение :rating, должен быть помещен в новый созданный массив, следуя правилу:начало массива и один в конце, пока не останется ни одного хэша.

Таким образом, конечный результат должен выглядеть следующим образом:

[
 {:rating=>4.0, :num=>74},
 {:rating=>4.0, :num=>72},
 {:rating=>3.5, :num=>72},
 {:rating=>1, :num=>1},
 {:rating=>1, :num=>1},
 {:rating=>3.5, :num=>37},
 {:rating=>4.0, :num=>23},
 {:rating=>4.0, :num=>38}
]

Любая помощь очень ценится.Благодаря.

Ответы [ 2 ]

1 голос
/ 22 сентября 2019

Возможно, немного сложное решение, но оно работает.Пожалуйста, посмотрите, пока я попытаюсь его реорганизовать

initial_array = [
    {:rating=>1, :num=>1},
    {:rating=>1, :num=>1},
    {:rating=>3.5, :num=>37},
    {:rating=>4.0, :num=>23},
    {:rating=>4.0, :num=>72},
    {:rating=>4.0, :num=>38},
    {:rating=>3.5, :num=>72},
    {:rating=>4.0, :num=>74}
]


length = initial_array.length
new_array = []

length.times do |i|
  is_odd = i % 2 == 1
  min_index = initial_array.map{|el| el[:rating]}.each_with_index.min.last
  if is_odd
    new_array.push(initial_array.delete_at(min_index))
  else
    new_array.unshift(initial_array.delete_at(min_index))
  end
end

p new_array

Основная идея заключается в том, чтобы каждый раз находить минимальный элемент в массиве и помещать его в новый массив один раз справа и один слева.

Минимальное значение определяется по рейтингу (map{|el| el[:rating]}), однако вы можете реализовать более сложную функцию, которая будет использовать rating и num в зависимости от вашей бизнес-логики.

0 голосов
/ 25 сентября 2019

Единственная интерпретация, которую я могу придумать для «разбить массив пополам», который соответствует желаемому результату, состоит в том, что хэши, которые должны быть отсортированы в порядке возрастания, - это те хеши h, для которых h[:num]меньше среднего значения h[:num] для всех хэшей h в массиве и того, что оставшиеся хэши должны быть отсортированы в порядке возрастания.

Предполагая, что эта интерпретация верна, и позволяя переменной arr удерживайте ваш массив, желаемый отсортированный массив можно получить следующим образом.

avg = arr.sum { |h| h[:num] }.fdiv(arr.size)
  #=> 39.75

arr.sort_by { |h| h[:num] < avg ? [h[:rating], h[:num]] : [-h[:rating], -h[:num]] }
  #=> [{:rating=>4.0, :num=>74},
  #    {:rating=>4.0, :num=>72},
  #    {:rating=>3.5, :num=>72},
  #    {:rating=>1,   :num=> 1},
  #    {:rating=>1,   :num=> 1},
  #    {:rating=>3.5, :num=>37},
  #    {:rating=>4.0, :num=>23},
  #    {:rating=>4.0, :num=>38}] 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...