将所有偶数索引整数乘以二
Multiply all even indexed integers by two
想要取固定数量的整数并将所有偶数(索引)整数乘以 2。我认为最好的方法是首先将 fixnum 变成一个数组。所以假设以下 16 位数字:a = 4408041234567901
我知道我可以:
a.to_s.split('')
这将 return 'a' 到 'stringed' 数字的数组。但后来我无法跟进:
a.map!.with_index {|i,n| i.even? n*2}
我想我有点卡在如何创建方法来执行此操作上。所以我的问题甚至可能是如何将那组数字变成 fixnums/integers 而不是字符串的数组。
要将其更改为数组,您可以这样做
a = 4408041234567901
arr = a.to_s.chars.map(&:to_i)
# => [4, 4, 0, 8, 0, 4, 1, 2, 3, 4, 5, 6, 7, 9, 0, 1]
您还可以将替代数字乘以 2
arr = a.to_s.chars.map.with_index {|n,i| i.even? ? n.to_i * 2 : n.to_i }
# => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
改进一点,可以用一个Hash
求乘数
h = {true => 2, false => 1}
a.to_s.each_char.map.with_index {|n,i| n.to_i * h[i.even?]}
编辑
每一步我都会解释,但如果你能自己想明白就更好了。打开 irb,输入 a.to_s
并检查输出。然后键入 a.to_s.chars
并检查输出等等..
a = 4408041234567901
even_odd = [:even, :odd].cycle
#=> #<Enumerator: [:even, :odd]:cycle>
如果索引从最高位(最左边)的数字开始:
a.to_s.each_char.map { |d|
(even_odd.next == :even) ? 2*d.to_i : d.to_i }
#=> [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
如果索引以个位数字开头:
s = a.to_s
even_odd.next if s.size.even?
s.each_char.map { |d| ( even_odd.next == :even) ? 2*d.to_i : d.to_i }
#=> [4, 8, 0, 16, 0, 8, 1, 4, 3, 8, 5, 12, 7, 18, 0, 2]
以下是基于零的索引从最高位开始的示例的步骤。
Array#cycle 将数组 [:even, :odd]
转换为枚举数:
even_odd = [:even, :odd].cycle
even_odd.next #=> :even
even_odd.next #=> :odd
even_odd.next #=> :even
even_odd.next #=> :odd
...
b = a.to_s
#=> "4408041234567901"
enum0 = b.each_char
#=> #<Enumerator: "4408041234567901":each_char>
枚举器 enum0
将 b
的数字传递给 map
。我本可以写成:
b = a.to_s.chars
# => ["4", "4", "0", "8", "0", "4", "1", "2",
# "3", "4", "5", "6", "7", "9", "0", "1"]
但这会创建一个中间数组。枚举器没有,因此效率更高。继续...
enum1 = enum0.map
#=> #<Enumerator: #<Enumerator: "4408041234567901":each_char>:map>
您可以将其视为 "compound enumerator"。我们可以通过将其转换为数组来查看其内容:
enum1.to_a
#=> ["4", "4", "0", "8", "0", "4", "1", "2",
# "3", "4", "5", "6", "7", "9", "0", "1"]
方法each
会将枚举器的每个元素传递到块中。证明:
enum1.each { |d| (enum.next == :even) ? 2*d.to_i : d.to_i }
# => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
我们可以使用 Enumerator#next 手动遍历 enum1
的元素。我们将值赋给块变量 d
并在块中执行计算以映射数字 d
:
d = enum1.next
#=> "4"
(enum.next == :even) ? 2*d.to_i : d.to_i
#=> (:even == :even) ? 2*"4".to_i : "4".to_i
#=> (true) ? 8 : 4
#=> 8 ("4" is mapped to 8)
d = enum1.next
#=> "4"
(enum.next == :even) ? 2*d.to_i : d.to_i
#=> (:odd == :even) ? 2*"4".to_i : "4".to_i
#=> (false) ? 8 : 4
#=> 4 ("4" is mapped to 4)
d = enum1.next
#=> "0"
#=> (:even == :even) ? 2*"0".to_i : "0".to_i
#=> (true) ? 0 : 0
#=> 8 ("0" is mapped to 0)
等等。
我更愿意从循环中完全删除条件,方法是创建一个 Enumerator
,其中包含您要乘以的系数(偶数索引为 2,奇数索引为 1。)
coef = [2, 1].cycle
这实际上创建了一个 Enumerator
,当 next
被调用时,它交替地 returns 2
和 1
。然后,您可以使用它来将您的 map
简化为:
a.to_s.each_char.map { |v| v.to_i * coef.next }
想要取固定数量的整数并将所有偶数(索引)整数乘以 2。我认为最好的方法是首先将 fixnum 变成一个数组。所以假设以下 16 位数字:a = 4408041234567901
我知道我可以:
a.to_s.split('')
这将 return 'a' 到 'stringed' 数字的数组。但后来我无法跟进:
a.map!.with_index {|i,n| i.even? n*2}
我想我有点卡在如何创建方法来执行此操作上。所以我的问题甚至可能是如何将那组数字变成 fixnums/integers 而不是字符串的数组。
要将其更改为数组,您可以这样做
a = 4408041234567901
arr = a.to_s.chars.map(&:to_i)
# => [4, 4, 0, 8, 0, 4, 1, 2, 3, 4, 5, 6, 7, 9, 0, 1]
您还可以将替代数字乘以 2
arr = a.to_s.chars.map.with_index {|n,i| i.even? ? n.to_i * 2 : n.to_i }
# => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
改进一点,可以用一个Hash
求乘数
h = {true => 2, false => 1}
a.to_s.each_char.map.with_index {|n,i| n.to_i * h[i.even?]}
编辑
每一步我都会解释,但如果你能自己想明白就更好了。打开 irb,输入 a.to_s
并检查输出。然后键入 a.to_s.chars
并检查输出等等..
a = 4408041234567901
even_odd = [:even, :odd].cycle
#=> #<Enumerator: [:even, :odd]:cycle>
如果索引从最高位(最左边)的数字开始:
a.to_s.each_char.map { |d|
(even_odd.next == :even) ? 2*d.to_i : d.to_i }
#=> [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
如果索引以个位数字开头:
s = a.to_s
even_odd.next if s.size.even?
s.each_char.map { |d| ( even_odd.next == :even) ? 2*d.to_i : d.to_i }
#=> [4, 8, 0, 16, 0, 8, 1, 4, 3, 8, 5, 12, 7, 18, 0, 2]
以下是基于零的索引从最高位开始的示例的步骤。
Array#cycle 将数组 [:even, :odd]
转换为枚举数:
even_odd = [:even, :odd].cycle
even_odd.next #=> :even
even_odd.next #=> :odd
even_odd.next #=> :even
even_odd.next #=> :odd
...
b = a.to_s
#=> "4408041234567901"
enum0 = b.each_char
#=> #<Enumerator: "4408041234567901":each_char>
枚举器 enum0
将 b
的数字传递给 map
。我本可以写成:
b = a.to_s.chars
# => ["4", "4", "0", "8", "0", "4", "1", "2",
# "3", "4", "5", "6", "7", "9", "0", "1"]
但这会创建一个中间数组。枚举器没有,因此效率更高。继续...
enum1 = enum0.map
#=> #<Enumerator: #<Enumerator: "4408041234567901":each_char>:map>
您可以将其视为 "compound enumerator"。我们可以通过将其转换为数组来查看其内容:
enum1.to_a
#=> ["4", "4", "0", "8", "0", "4", "1", "2",
# "3", "4", "5", "6", "7", "9", "0", "1"]
方法each
会将枚举器的每个元素传递到块中。证明:
enum1.each { |d| (enum.next == :even) ? 2*d.to_i : d.to_i }
# => [8, 4, 0, 8, 0, 4, 2, 2, 6, 4, 10, 6, 14, 9, 0, 1]
我们可以使用 Enumerator#next 手动遍历 enum1
的元素。我们将值赋给块变量 d
并在块中执行计算以映射数字 d
:
d = enum1.next
#=> "4"
(enum.next == :even) ? 2*d.to_i : d.to_i
#=> (:even == :even) ? 2*"4".to_i : "4".to_i
#=> (true) ? 8 : 4
#=> 8 ("4" is mapped to 8)
d = enum1.next
#=> "4"
(enum.next == :even) ? 2*d.to_i : d.to_i
#=> (:odd == :even) ? 2*"4".to_i : "4".to_i
#=> (false) ? 8 : 4
#=> 4 ("4" is mapped to 4)
d = enum1.next
#=> "0"
#=> (:even == :even) ? 2*"0".to_i : "0".to_i
#=> (true) ? 0 : 0
#=> 8 ("0" is mapped to 0)
等等。
我更愿意从循环中完全删除条件,方法是创建一个 Enumerator
,其中包含您要乘以的系数(偶数索引为 2,奇数索引为 1。)
coef = [2, 1].cycle
这实际上创建了一个 Enumerator
,当 next
被调用时,它交替地 returns 2
和 1
。然后,您可以使用它来将您的 map
简化为:
a.to_s.each_char.map { |v| v.to_i * coef.next }