2017-06-26 80 views
-2

我得到这个数组:如何在Ruby中嵌套数组中的数字?

array = [["R.M", 20], ["R.U-CS", 3], ["R.M-TIC", 3], ["R.J.CONF", 20]] 

sum的数值,所以我已经转换此成一个单一的阵列,通过使用flatten

array = array.flatten 
#=> ["R.M", 20, "R.U-CS", 3, "R.M-TIC", 3, "R.J.CONF", 20] 

然后:

a = [] 
array.each do |r| 
    a << r if r.class == Fixnum 
end 
a 

这可行,但我正在寻找一个更简单的解决方案,可能首先将数组转换为“仅有的numeric”数组:

[20, 3, 3, 20] 
+1

你可以,例如。结合'选择'与'is_a?' –

+0

谢谢:),它适用于我 –

+0

你有什么问题的代码?你的代码有什么问题?你有错误信息吗?什么是错误信息?你得到的结果不是你期待的结果吗?你期望得到什么结果?为什么?你得到的结果是什么?两者有什么不同?你正在观察的行为不是所期望的行为?什么是期望的行为,为什么,观察到的行为是什么,以及它们以何种方式不同?请提供[mcve]。 [所以]不是“写我的代码给我的服务”!如果您正在寻找*那*,聘请程序员。 –

回答

14

不是很明显,但是你可以通过一个类或模块来grep选择它的实例:

array.grep(Integer) 
#=> [20, 3, 3, 20] 

array.grep(Numeric) 
#=> [20, 3, 3, 20] 

grep_v排除其实例:

array.grep_v(String) 
#=> [20, 3, 3, 20] 

这可行,因为grep使用===进行模式匹配。如果你传递一个类,它调用Module#===(每类模块)如果对象是接收器的一个实例,它返回true

Integer === 20 
#=> true 

Integer === 'foo' 
#=> false 

然而,您的实际问题可以多得到解决更轻松。鉴于这种阵列:

array = [["R.M", 20], ["R.U-CS", 3], ["R.M-TIC", 3], ["R.J.CONF", 20]] 

并假设第二值始终是一个号码,则可以使用sum与块:

array.sum { |string, number| number } 
#=> 46 

或总结每个子阵列的last值:(这是在这种情况下,相同)

array.sum(&:last) 
#=> 46 
+2

这个!我永远忘记了这个美好的'grep'。 **这是正确的答案,并应标明** – mudasobwa

+4

@mudasobwa:有很多种方法对皮肤一只猫:) –

+1

@SergioTulentsev yes和no。为了让这只猫开心,应该使用最可读的方式来完成任务。就是这个。 – mudasobwa

1
array.delete_if { |x| x.kind_of(String) } 
0

按照下面的代码

array.reject { |c| c.class.name.eql?('String') } 

随着is_a?

array.reject { |c| c.is_a?(String) } 
+2

为什么类名检查而不是'is_a?'? –

+0

我们可以同时使用@SergioTulentsev –

+0

除了一个错误:) –

1
array.map { |item| item if item.is_a? Integer }.compact 

# [20, 3, 3, 20] 

更紧凑:

array.select { |item| item.is_a? Integer } 

或者更短:

array.select &Integer.method(:===) 
+1

你在这里误用'map'。 –

+0

'map.compact'比'select'多一个循环。 – mudasobwa

+0

你的'select'块中的'item if'部分是多余的。 – Stefan

0

使用select如果你想永久改变你的变量array与只整数内容从数组

array = ["R.M", 20, "R.U-CS", 3, "R.M-TIC", 3, "R.J.CONF", 20] 
array.select { |tmp| tmp.is_a?(Integer) } 
#=> [20, 3, 3, 20] 

使用select!只选择整数内容

+0

Ruby不是Python或Java。当'select'足够时,无需编写'select()'。 –

+0

@EricDuminil点指出..从'Enumerable'一些其他方法,如'注入({})'需要在args ..所以括号只是滑动,只是使用枚举方法 – sa77

+2

是。请注意'inject'并不总是需要一个参数。 –

3

人们可能会使用类'case-equality Module#===来确定一个元素类并拒绝字符串:

array = ["R.M", 20, "R.U-CS", 3, "R.M-TIC", 3, "R.J.CONF", 20] 
array.reject &String.method(:===) 
#⇒ [ 
# [0] 20, 
# [1] 3, 
# [2] 3, 
# [3] 20 
# ] 
+0

哇,谢谢你的提示! –

0

如果您阵列格式应该是你的榜样,那么这将工作:

array.select.with_index { |_,i| i.odd? } #=> [20, 3, 3, 20]