这是一个红宝石数组:
array = ['x', 3, 0, 4, 4, 7]
我想通过array
进行映射,将数组中的每个整数(0
除外)减去2,然后返回一个新数组。
当有字母时,将不会对字母进行任何更改。
示例输出:
['x', 1, 0, 2, 2, 5]
这就是我所拥有的,但是我收到了错误消息:“未定义的方法整数?”有人可以告诉我这是什么问题吗?
def minusNumber(array)
array.map do |e|
if e.integer? && e !== 0
e - 2
end
end
end
答案 0 :(得分:2)
这是另一种看法:
{
"index": "notifications_production",
"sort" : {"created_at" : {"order" : "desc"}},
"query": {
"bool": {
"must": [
{ "match_all": {} }
],
"filter": [
{ "match": { "company_id": 5054 }},
{
"range" : {
"created_at" : {
"gte" : "now-30d",
"lte" : "now"
}
}
}
]
}
},
"script_fields" : {
"sequence2" : {
"script" : {
"lang": "painless",
"source": "'<a href=#>' + params._source.file_name + '</a>'"
}
}
},
"_source": true
}
很遗憾,您必须保留没有减去2的元素。我真的很想做这样的事情
array = ['x', 3, 0, 4, 4, 7]
transformed = array.map do |e|
case e
when 0, String
e
when Integer
e - 2
else
fail 'unexpected input'
end
end
transformed # => ["x", 1, 0, 2, 2, 5]
还找不到方法(保留未处理的项目)。
答案 1 :(得分:2)
此处的其他答案将与您当前的输入配合使用。像这样:
def minusNumber(array)
array.map do |e|
if e.is_a?(Integer) && e != 0
e - 2
else
e
end
end
end
但是这里有一个更灵活的解决方案。对于您现在所在的位置,这可能有点太先进了,但是所有学习都是不错的学习:-)
Ruby是一种允许变量中具有多态性的语言。使用方法的示例输入,您可以看到变量e
可以包含String
对象或Integer
对象。但是它实际上可能包含 any 类型的对象,并且Ruby不会在乎一点,除非它在使用变量时遇到错误。
所以。在您的示例中,您需要在输出中保留Integer
。但是,如果将来需要传递包含一些Score
对象的数组,而在输出中也需要这些对象,该怎么办?这是您甚至还没有写过的全新课程,但是您知道以后会继续学习。有一种方法可以重新编写将要在将来使用的类的方法,以及将来可能编写的所有其他Integer
类型的类。
代替使用#is_a?
检查对象的类型,而使用#respond_to?
检查对象实现的方法。
任何可用作整数should implement the #to_int
method的类。 Integer
当然可以,您将来的Score
类可以,但是String
可以。其他不能视为整数的类也没有。因此,这将适用于所有类型的值,正确地将响应#to_int
的值与不响应的值分开。
def minusNumber(array)
array.map do |e|
if e.respond_to?(:to_int) && e != 0
e - 2
else
e
end
end
end
同样,这些东西可能会有点高级,但是早点养成习惯就变量的方法(而不是类型)进行思考是一种很好的习惯。这种思维方式将在以后帮助您。
答案 2 :(得分:0)
又矮又甜。
array.map { |v| v.is_a?(Integer) && !v.zero? ? v - 2 : v }
这消除了所有不必要的case
语句,多次迭代和转换。只需取每个元素,如果它是一个整数且大于0,则减去2,否则不执行任何操作。
答案 3 :(得分:0)
您可以执行此操作而无需检查类型。
使用kind_of?是一种代码气味,说明您的代码是过程性的,而不是面向对象的… https://www.sandimetz.com/blog/2009/06/12/ruby-case-statements-and-kind-of
def someMethod(arr)
arr.map do |item|
next item unless item.to_i.nonzero?
item - 2
end
end
someMethod(["x", 3, 0, 4, 4, 7])
> ["x", 1, 0, 2, 2, 5]
答案 4 :(得分:-1)
如上面的注释中所述,您应该使用is_a?
方法检查元素的数据类型。下面的代码应按预期工作:
def minusNumber(array)
array.map do |e|
if e.is_a?(String) || e == 0
e
else
e - 2
end
end
end
代替 if 语句,您也可以这样做:
(e.is_a?(String) || e == 0 ) ? e : e-2
请注意,除非使用map!
答案 5 :(得分:-1)
我认为这是清晰而优雅的:
array.map { |v| v.is_a?(Integer) && v == 0 ? v : v -2 }