问题
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