All indexes having the same character in nested array Ruby

南笙酒味 提交于 2019-12-25 02:56:04

问题


I'm trying to see if an index, say index 3, all has the same character. For example:

nested_array =   [[47, 44, 71, 'x', 88],
                  [22, 69, 75, 'x', 73],
                  [83, 85, 97, 'x', 57],
                  [25, 31, 96, 'x', 51],
                  [75, 70, 54, 'x', 83]]

As we can see, index 3 has all x'x in it instead of numbers. I want to be able to verify if ALL of the indexes have an x, if so, program returns true. If all but 1 have x's it would return false.

I have now implemented this conditional statement as it iterates through each index looking for a value the size equal to 1. This seemed to do the trick.

if array.map {|zero| zero[0]}.uniq.size == 1
  return true
elsif array.map {|one| one[1]}.uniq.size == 1
  return true
elsif array.map {|two| two[2]}.uniq.size == 1
  return true
elsif array.map {|three| three[3]}.uniq.size == 1
  return true
elsif array.map {|four| four[4]}.uniq.size == 1
  return true
else
  return false
end

回答1:


nested_array.empty? || nested_array.map {|row| row[3]}.uniq.one?

The special condition for empty arrays is necessary because they trivially fulfill any condition that is specified for each element, but the uniqueness test would not pick it up. Feel free to drop it if you will not in fact have an empty array, or the test should fail if the array is empty.

EDIT: Seems I misunderstood the question - try this as an alternative to your multi-if:

nested_array.transpose.any? { |column| column.uniq.one? }

"When you flip rows and columns, does any of the rows (that used to be columns) have only one unique element?"

(if you want true for [], again, prefix with nested_array.empty? || ...).

EDIT: Thanks to spickermann, replaced .size == 1 with .one?. It really does read better.




回答2:


You did not specify that all elements of nested_array are necessarily of the same size, so I will offer a solution does not have that as a requirement:

nested_array =   [[47, 44, 71, 'x', 88],
                  [75, 70, 54, 'x', 83, 85, 90],
                  [22, 69, 75, 'x', 73],
                  [83, 85, 97, 'x', 57],
                  [25, 31, 96, 'x', 51, 33]]

nested_array.first.zip(*nested_array[1..-1]).any? {|row| row.uniq.size==1}
  #=> true

We have:

b = nested_array.first.zip(*nested_array[1..-1])
  #=> [[47, 75, 22, 83, 25],
  #    [44, 70, 69, 85, 31],
  #    [71, 54, 75, 97, 96],
  #    ["x", "x", "x", "x", "x"],
  #    [88, 83, 73, 57, 51]] 

b.any? { |row| row.uniq.size == 1 }
  #=> true

Initally, I had:

nested_array.first.zip(*nested_array[1..-1]).any? {|row|
  row[1..-1].all? { |e| e == row.first } }

rather than { |row| row.uniq.size==1 }. As @Amadan points out, the former should be a bit faster.

If the question is whether a specific element of b contains all the same values:

index = 3
a = nested_array.first.zip(*nested_array[1..-1])
(index >= a.size) ? false : a[index].uniq.size==1
  #=> true


来源:https://stackoverflow.com/questions/29886062/all-indexes-having-the-same-character-in-nested-array-ruby

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!