【问题标题】:Finding index of elements in an array of arrays查找数组数组中元素的索引
【发布时间】:2016-06-09 20:27:31
【问题描述】:

我有一个数组数组:

[
  [0,0,0,0],
  [0,1,0,0],
  [0,0,0,1],
  [0,0,0,0]
]

我想查找值为1 的项目的索引(行和列)。我怎样才能做到这一点?我需要这些值,以便我可以操纵1s 两侧的单元格。我查看了find.index 方法,但我不确定。

【问题讨论】:

  • 我想知道为什么人们一直在这种情况下使用嵌套数组。扁平数组更容易处理。
  • 当你给出一个例子时,请为每个输入对象分配一个变量。这样就可以在答案和 cmets 中引用该变量。除了一个答案之外,所有答案都是从定义数组开始的。如果你写了arr =[[0,0....]],那么这些都不需要——答案只会引用arr。我意识到你是新来的。这只是一个提示,而不是批评。

标签: arrays ruby indexing find


【解决方案1】:

考虑使用Matrix 类。

require 'matrix'

arr = [
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
]    

target = 1

Matrix[*arr].each_with_index.with_object([]) { |(e,row,col),a|
  a << [row,col] if e==target }
  #=> [[1, 1], [2, 3]]

我喜欢这样的阅读方式。

【讨论】:

  • 感谢大家的帮助
  • selectmap 的组合也可以:m.each_with_index.select { |e, r, c| e == 1 }.map { |e, r, c| [r, c] }
【解决方案2】:

没那么花哨,但你可以使用两个循环:

ary = [
  [0, 0, 0, 0],
  [0, 1, 0, 0],
  [0, 0, 0, 1],
  [0, 0, 0, 0]
]

result = []
ary.each_with_index do |row, i|
  row.each_with_index do |value, j|
    result << [i, j] if value == 1
  end
end
result
#=> [[1, 1], [2, 3]]

【讨论】:

  • ...或ary.each_index {|i| ary.first.each_index {|j| result &lt;&lt; [i,j] if ary[i][j] == 1}}
【解决方案3】:
z = [
  [0,0,0,0],
  [0,1,0,0],
  [0,0,0,1],
  [0,0,0,0]
]

首先,让我们找到匹配的行:

rows = z.each_with_index.select { |row, index| row.include? 1}.map(&:last)
# => [1, 2]

然后对于每一行,让我们找到匹配的1 的索引:

cols = rows.map {|row| z[row].each_with_index.select { |item, index| item == 1}.map(&:last) }
# => [[1], [3]]

如果需要,我们可以使用zip 组合它们:

rows.zip(cols)
# => [[1, [1]], [2, [3]]]

即使一行z 包含多次出现的1,上述方法仍然有效

例如,如果我们有:

z = [
  [1,0,0,1],
  [0,1,0,0],
  [0,0,0,1],
  [1,1,1,0]
]

然后

rows = z.each_with_index.select { |row, index| row.include? 1}.map(&:last)
# => [0, 1, 2, 3]
cols = rows.map {|row| z[row].each_with_index.select { |item, index| item == 1}.map(&:last) }
# => [[0, 3], [1], [3], [0, 1, 2]]
rows.zip(cols)
# => [[0, [0, 3]], [1, [1]], [2, [3]], [3, [0, 1, 2]]]

【讨论】:

  • 隐含地指出蒂蒙·冯克回答中的一个缺陷的好点。
【解决方案4】:

Ruby 有一个非常灵活的函数式Enumerable 模块,它包含在许多标准集合(数组、哈希、集合)中。您可以找到文档at ruby-doc.org

在最大#rows * 2 #columns 时间内解决此问题的一个很好的单行方法如下:

matrix
  .each.with_index
  .inject([]) { |acc, (el,idx)| el.include?(1) ? acc.push([idx, el.index(1)]) : acc }
# => [[1,1],[2,3]]

【讨论】:

  • 如果一行包含多个1,这将不起作用
【解决方案5】:
a = [
  [0,0,0,0],
  [0,1,0,0],
  [0,0,0,1],
  [0,0,0,0]
].flatten

a.each.with_index.select{|e, _| e == 1}.map{|_, i| i.divmod(4)}
# => [[1, 1], [2, 3]]

被解释为(第 1 行,第 1 列)和(第 2 行,第 3 列)。

【讨论】:

  • @Stefan 可以得到4作为原始数组的第一个元素的长度,但我的建议是从头开始有一个平面数组,加上@987654323的附加信息@.
  • 无论是那个还是带有[x, y] =&gt; value对的哈希
猜你喜欢
  • 2014-11-15
  • 2013-08-26
  • 2015-08-19
  • 1970-01-01
  • 2015-07-29
  • 2019-01-12
  • 1970-01-01
  • 2019-07-12
  • 2021-11-03
相关资源
最近更新 更多