Самый элегантный способ проверить равенство размеров подмассивов в многомерном массиве? - PullRequest
2 голосов
/ 15 февраля 2009

(можете ли вы сказать, что я изучаю Ruby сегодня?))

Я хочу определить, является ли многомерный массив, с которым я работаю, «прямоугольником», т. Е. Строки имеют одинаковый размер. Вот что я делаю, это работает, но кажется неуклюжим.

if @myArray[0].size != @myArray[0..@myArray.size].size
  raise "This array is not a rectangle."
end

По сути, я проверяю, равен ли размер первого массива размеру всего остального массива. Почему-то, кажется, этого недостаточно "рубиновый", понимаешь? У кого-нибудь есть более элегантные решения?

Ответы [ 3 ]

3 голосов
/ 15 февраля 2009

Попробуйте:

raise 'This array is not a rectangle' \
  if myArray[1..-1].any? { |row| row.size != myArray[0].size }

Смотрите http://www.ruby -doc.org / core / classes / Array.html (оператор []) и http://www.ruby -doc.org / core / classes / Enumerable.html (метод any?)

1 голос
/ 15 февраля 2009

Я мог бы сделать что-то вроде того, что опубликовали другие, или

if 1 == @myArray.map { |row| row.size }.uniq.size
     # ...
end

Вы должны заметить, что ваш пример кода не делает то, что вы думаете

# this creates an array that holds a slice
# of elements from @myArray ( a to b inclusive )
@myArray[ a .. b ]
# this just gets the size of the slice
# (equal to b-a+1)
@myArray[a .. b].size

Итак, ваше утверждение if на самом деле сравнивалось размер строки с размером столбца (плюс 1, поскольку он был от 0 до @ myArray.size включительно). Он не сравнивал размер каждого ряда с первым. Для этого вам нужно явно выполнить итерацию, используя каждый, карту или какой-либо другой метод.

1 голос
/ 15 февраля 2009

Это не вызовет ошибку:

@my_array = [[1,2,3,4],[1,2,3,4]]
for row in @my_array
  if row.size != @my_array.first.size
    raise "This array is not a rectangle"
  end
end

Это вызовет ошибку:

@my_array = [[1,2,3,4],[1,2,3]]
for row in @my_array
  if row.size != @my_array.first.size
    raise "This array is not a rectangle"
  end
end

Этот код перебирает все вложенные массивы внутри массива и проверяет, не совпадает ли их размер с размером первого, а затем выдает ошибку, если это так.

...