我目前正在学习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|
我的直觉告诉我,这不是编写内循环的方法。
答案 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;它列出了Enumerable
。 Enumerable
旨在成为&#34; mixin&#34;,它可以将方法添加到其他类(甚至是您自己的类)。 [旁注:事实上,如果您查看Array
的文档,它也包含Enumerable
。 Ruby数组可用的这些方法的组合使它们非常强大,为什么我建议学习它们]。 select
method取block,它将返回给定块为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的答案(或类似的东西)。