如何找到数组["5 7", "2 2", "6 7", "10 4", "1 3", "6 7", "9 1", "7 8", "1 7", "4 6"]
中两个连续项的差异。
输出应为[3,5],[ - 4,-5],[ - 4,3]等。
[3,5]来自[5-2,7-2]。
我有以下内容,但我不知道如何从这里开始。
["5 7", "2 2", "6 7", "10 4", "1 3", "6 7", "9 1", "7 8", "1 7", "4 6"]
.each_cons(2){|a| # need more here }
答案 0 :(得分:3)
这是使用Ruby的Matrix课程的一种方法。下面我提到第二种不使用矩阵运算的方法,但我认为第一种方法更好。这两种方法都允许数组中的字符串包含两个以上的整数。
<强>代码强>
require 'matrix'
def diff(arr)
arr.map { |str| str.scan(/\d+/).map(&:to_i) }.each_cons(2).map { |e,f|
(Matrix[e]-Matrix[f]).to_a }.flatten(1)
end
示例强>
arr = ["5 7", "2 2", "6 7", "10 4", "1 3", "6 7", "9 1", "7 8", "1 7", "4 6"]
def diff(arr)
#=> [[ 3, 5], [-4, -5], [-4, 3], [ 9, 1], [-5, -4],
# [-3, 6], [ 2, -7], [ 6, 1], [-3, 1]]
<强>解释强>
对于上面的示例,首先将字符串转换为包含两个整数的数组:
b = arr.map { |str| str.scan(/\d+/).map(&:to_i) }
#=> [[5, 7],[2, 2],[6, 7],[10, 4],[1, 3],[6, 7],[9, 1],[7, 8],[1, 7],[4, 6]]
正如您所做的那样,使用Enumerable#each_cons处理每对数组:
c = b.each_cons(2)
#=> #<Enumerator: [[5, 7], [2, 2], [6, 7], [10, 4], [1, 3],
# [6, 7], [9, 1], [7, 8], [1, 7], [4, 6]]:each_cons(2)>
要查看此枚举器的内容:
c.to_a
#=> [[[ 5, 7], [2, 2]], [[2, 2], [6, 7]], [[6, 7], [10, 4]],
# [[10, 4], [1, 3]], [[1, 3], [6, 7]], [[6, 7], [ 9, 1]],
# [[ 9, 1], [7, 8]], [[7, 8], [1, 7]], [[1, 7], [ 4, 6]]]
将每一对映射到差异:
d = c.map { |e,f| (Matrix[e]-Matrix[f]).to_a }
#=> [[[3, 5]], [[-4, -5]], [[-4, 3]], [[9, 1]], [[-5, -4]],
# [[-3, 6]], [[2, -7]], [[6, 1]], [[-3, 1]]]
最后,压平一个级别:
d.flatten(1)
#=> [[ 3, 5], [-4, -5], [-4, 3], [ 9, 1], [-5, -4],
# [-3, 6], [ 2, -7], [ 6, 1], [-3, 1]]
<强>替代强>
您不希望在map
块中使用Matrix类,Array#transpose和Enumerable#reduce(又名inject
):
arr.map { |str| str.scan(/\d+/).map(&:to_i) }.each_cons(2).map { |e|
e.transpose.map { |a| a.reduce(&:-) } }