在ruby中使用嵌套循环获取一对唯一的数组?

时间:2017-11-30 23:10:59

标签: ruby

我目前正在学习ruby并且对它很新。我通常在javascript中编写代码,但是因为我明年进入训练营,所以在我的队列开始之前,我会自己学习ruby。因此,我试图解决的实践问题是获得等于某个数字的元素索引,在这种情况下,我们举一个例子0。

我可以为JS做这个没问题,但我正在学习如何用Ruby编写。

//JS 
for(let i = 0; i < arr.length; i++){
    for(let j = i + 1; j < arr.length; j++){
       if(arr[j] + arr[i] === 0){
           someVar.push([i,j]);
       }
    }
}

上面的块代码显示了我获取每个唯一对的位置,并且这些对中的一个返回一个和0,它们的索引被推入结果中。

我仍然非常了解ruby如何编写循环,并且有很多方法可以做到这一点。

  def two_sum(nums)
  result = []
  n = nums.length

  n.times do |i|
    n.times do |j|

      if nums[i] + nums[j] == 0
        result.push([i,j])
      end
    end
  end
  result
end

我尝试过这样做,但它并没有给我正确的输出。我也理解n.times do |j|for(let j = i + 1; j < arr.length; j++)不同。但我不知道怎么写这个,所以我做了类似的事情:

n.times do |i|
  x = i + 1
  x.times do |j|

我的直觉告诉我,这不是编写内循环的方法。

2 个答案:

答案 0 :(得分:4)

只需select所有对中的适当总和(2的组合)。

def two_sum(nums)
  nums.combination(2).select{|pair| pair.sum == 3}
end

修改:有关正在进行的更多详情:

如您所知,我们传入一个名为nums的数组。如果您转到documentation for Array,则会看到名为combination的方法。顺便说一句,我高度建议您作为Ruby的新手,熟悉Array(以及Enumerable上的所有方法,我和#{1}}。我会解释一下)。 combination方法&#34;产生长度为n&#34;的所有元素组合。我们将使用n = 2:

p [3,2,1,0,5].combination(2).to_a
#=> [[3, 2], [3, 1], [3, 0], [3, 5], [2, 1], [2, 0], [2, 5], [1, 0], [1, 5], [0, 5]]

现在如果你省略了上面的.to_a,你就会发现combination的输出实际上是Enumerator。如果你仔细查看the documentation,你会看到&#34;包含的模块&#34;它列出了EnumerableEnumerable旨在成为&#34; mixin&#34;,它可以将方法添加到其他类(甚至是您自己的类)。 [旁注:事实上,如果您查看Array的文档,它也包含Enumerable。 Ruby数组可用的这些方法的组合使它们非常强大,为什么我建议学习它们]。 select methodblock,它将返回给定块为true的所有元素。因此,我们检查每个元素以查看总和是否为3,例如:

[2,1].sum == 3
#=> true (and therefore [2,1] will be included in the output)

select的输出,因此two_sum方法的输出是所有匹配的数组(块为真的元素)。

修改2

Stefan在评论中指出,上述结果是返回值,而不是指数。解决这个问题的一种方法是为结果添加索引查找:

def two_sum(nums)
  nums.combination(2)
      .select{|pair| pair.sum == 3}
      .map{|pair| [nums.index(pair[0]), nums.index(pair[1])] }
end

不完全简洁,但现在至少输出指数:)

答案 1 :(得分:1)

如果您希望代码类似于您的JS代码段,那么这是使用适当的ruby循环的版本。

0.upto(arr.length - 1) do |i|
  (i + 1).upto(arr.length - 1) do |j|
    if arr[i] + arr[j] == 0
      result.push([i, j])
    end
  end
end

但更多惯用的红宝石将是MarkThomas的答案(或类似的东西)。