2012-01-19 8 views
51

Digamos que estoy tratando de eliminar elementos de la matriz a = [1,1,1,2,2,3]. Si realizo el siguiente:Eliminando elementos de la matriz Ruby

b = a - [1,3] 

Entonces voy a conseguir:

b = [2,2] 

Sin embargo, quiero que el resultado sea

b = [1,1,2,2] 

es decir, que sólo se quita una instancia de cada elemento en el vector sustraído no todos los casos. ¿Hay alguna manera simple en Ruby para hacer esto?

+0

si se resta '[1,1,3]' qué quiere terminar arriba con 'b = [1,2,2]'? ¿O eso nunca va a suceder? – seph

Respuesta

63

Usted puede hacer:

a= [1,1,1,2,2,3] 
delete_list = [1,3] 
delete_list.each do |del| 
    a.delete_at(a.index(del)) 
end 

resultado: [1, 1, 2, 2]

+1

Entonces, la sustracción de matriz en realidad es disjunta: ¿establecer? –

+1

Diferencia de matriz --- Devuelve una nueva matriz que es una copia de la matriz original, eliminando cualquier elemento que también aparezca en other_ary. (Si necesita un comportamiento similar al de un conjunto, consulte la clase de biblioteca Conjunto) [enlace] (http://www.ruby-doc.org/core-1.9.3/Array.html) – Norm212

+2

Si desea eliminar todas las instancias de elementos en 'delete_list', puedes hacer esto. 'b = a.each.reject {| x | delete_list.each.include? x} ' – Archonic

2

No es muy simple, pero:

a = [1,1,1,2,2,3] 
b = a.group_by {|n| n}.each {|k,v| v.pop [1,3].count(k)}.values.flatten 
=> [1, 1, 2, 2] 

también maneja el caso para los múltiplos de la 'sustraer':

a = [1,1,1,2,2,3] 
b = a.group_by {|n| n}.each {|k,v| v.pop [1,1,3].count(k)}.values.flatten 
=> [1, 2, 2] 

EDITAR: esto es mor Es una mejora que combina Norm212 y mi respuesta para hacer una solución "funcional".

b = [1,1,3].each.with_object(a) { |del| a.delete_at(a.index(del)) } 

Póngalo en una lambda, si es necesario:

subtract = lambda do |minuend, subtrahend| 
    subtrahend.each.with_object(minuend) { |del| minuend.delete_at(minuend.index(del)) } 
end 

a continuación:

subtract.call a, [1,1,3] 
+0

No, el orden podría ser alterado. Parece que Norm212 conserva el orden. – seph

+0

@Michael, consulte ediciones – seph

3
[1,3].inject([1,1,1,2,2,3]) do |memo,element| 
    memo.tap do |memo| 
    i = memo.find_index(e) 
    memo.delete_at(i) if i 
    end 
end 
Cuestiones relacionadas