我有两个数组。第一个是带有名称和数量的字符串数组。第二个是一系列字母。
li.menu-item {
position: relative;
top: 50px;
left: 300px;
}
我想创建第三个数组,根据a2对来自a1的内容进行排序,并根据第一个数组中的信息返回数字。因为a2有" B"和" Z",我需要扫描第一个数组,查找以字母B和Z开头的所有条目,并加上数字。
我的最终目标是在第三个数组上返回总和,如下所示:
a1 = ["ASLK 50", "BSKD 150", "ZZZZ 100", "BSDF 50"]
a2 = ["B", "Z"]
因为" A"不是在a2上,它不计算在内。
我能够从a1中提取信息:
a3 = ["B = 200", "Z = 100"]
我在比较a1和a2时遇到了麻烦。我尝试过不同的方法,例如:
arr = a1.map{|el| el[0] + " : " + el.gsub(/\D/, '\1')}
#=> ["A : 50", "B : 150", "Z : 100", "B : 50"]
可选地,
a1.find_all{|i| i[0] == a2[0]} #=> only returns the first element of a2. How can I iterate through a2?
我认为要么解决它,但我不能把它想到工作代码。我该如何实现这两种方法?有没有更有效的方法呢?
答案 0 :(得分:2)
我将如何做到这一点:
a1 = ["ASLK 50", "BSKD 150", "ZZZZ 100", "BSDF 50"]
a2 = ["B", "Z"]
a3 = a1.each_with_object(Hash.new(0)) do |a,obj|
obj[a[0]] += a.split.last.to_i if a2.include?(a[0])
end.map {|a| a.join(" = ")}
#=>["B = 200", "Z = 100"]
第一步将它们全部添加到Hash
中,方法是将值与第二个数组中包含的每个第一个字母相加。
第二步提供所需的输出
如果您想要哈希,只需取消最后一次调用地图,您就可以了。
{"B" => 200, "Z" => 100}
答案 1 :(得分:2)
根据您的要求运行,您想要将其转为:
a1 = ["ASLK 50", "BSKD 150", "ZZZZ 100", "BSDF 50"]
a2 = ["B", "Z"]
进入:a3 = ["B = 200", "Z = 100"]
a3 = a2.map do |char|
sum = a1.reduce(0) do |sum, item|
name, price = item.split(" ")
sum += price.to_i if name[0].eql?(char)
sum
end
"#{char} = #{sum}"
end
答案 2 :(得分:1)
不是定义像Array
这样的["B = 200", "Z = 100"]
,而是将其定义为映射 - 即以下Hash
对象更为明智:
{"B" => 200, "Z" => 100}
至于实施方式,有很多方法可以做到。这只是一种方法:
a1 = ["ASLK 50", "BSKD 150", "ZZZZ 100", "BSDF 50"]
a2 = ["B", "Z"]
result = a2.map do |letter|
[
letter,
a1.select {|str| str[0] == letter}
.inject(0) {|sum, str| sum += str[/\d+/].to_i}
]
end.to_h
puts result # => {"B"=>200, "Z"=>100}
说明:
Array#to_h
将对数组[["B", 200], ["Z", 100]]
转换为Hash
:{"B" => 200, "Z" => 100}
。a1.select {|str| str[0] == letter}
仅选择a1
中第一个字母为哈希键字符的元素。inject(0) {|sum, str| sum += str[/\d+/].to_i}
将所有数字相加,保护措施默认为零(而不是意外地将nil
抛出)。答案 3 :(得分:1)
这与@ engineermnky的答案非常相似。
r = /
\A[A-Z] # match an upper case letter at the beginning of the string
| # or
\d+ # match one or more digits
/x # free-spacing regex definition mode
a1.each_with_object(Hash.new(0)) do |s,h|
start_letter, value = s.scan(r)
h[start_letter] += value.to_i if a2.include?(start_letter)
end.map { |k,v| "#{k} = #{v}" }
#=> ["B = 200", "Z = 100"]
Hash.new(0)
通常被称为“计数哈希”。有关解释,请参阅类方法Hash::new的文档。
正则表达式匹配字符串的第一个字母或一个或多个数字。例如,
"ASLK 50".scan(r)
#=> ["A", "50"]