2011-03-30 7 views
18

que tienen una línea de textoComprobar si un elemento de una matriz existe en parte en una cadena dada

this is the line 

y quiero volver true si uno de los elementos de dicha matriz:

['hey', 'format', 'qouting', 'this'] 

es una parte de la cadena dada arriba.

Así que para la línea anterior debería volver true.

Para esta línea hello my name is martin no debería.

include? pero no saben cómo usarlo aquí si ayuda en absoluto.

Respuesta

24
>> s = "this is the line" 
=> "this is the line" 
>> ['hey', 'format', 'qouting', 'this'].any? { |w| s =~ /#{w}/ } 
=> true 
>> ['hey', 'format', 'qouting', 'that'].any? { |w| s =~ /#{w}/ } 
=> false 
>> s2 = 'hello my name is martin' 
=> "hello my name is martin" 
>> ['hey', 'format', 'qouting', 'this'].any? { |w| s2 =~ /#{w}/ } 
=> false 
+1

Bueno, eso fue rápido, gracias. ¿Te importaría explicar lo que sucede aquí 's = ~/# {w} /'? –

+2

Es una coincidencia de expresión regular. Como la expresión regular en Ruby admite la interpolación de cadenas, la utilizo para crear una de las cadenas en la matriz. –

+2

Debo agregar que esto también volverá verdadero si una palabra es parte de una palabra más larga en la cadena, por lo que si no quiere eso, tendrá que coincidir con los límites de las palabras '/ \ b # [w} \ b/'. –

1
> arr = ['hey', 'format', 'qouting', 'this'] 
=> ["hey", "format", "qouting", "this"] 
> str = "this is the line" 
=> "this is the line" 
> str.split(" ").find {|item| arr.include? item } 
=> "this" 
> str.split(" ").any? {|item| arr.include? item } 
=> true 
+1

puede ir al de otra manera también 'arr.any? {| elemento | str.include? item} ' – rubyprince

+0

sí, eso está bien ... :). Acabo de empezar a ruby ​​... seguir haciendo ruby ​​en C# way :( – RameshVel

6

se puede dividir la strling en una matriz, y comprobar si la intersección entre la matriz y la matriz recién dividido, como tal.

Esto es muy útil, ya que le va a dar más que un verdadero falso, se le dará las cadenas coincidentes.

> "this is the line".split(' ') & ["hey", "format", "quoting", "this"] 
=> ["this"] 

Si se necesitaba un verdadero/falso fácilmente se podría hacer:

> s = "this is the line" 
=> "this is the line" 
> intersection = s.split(' ') & ["hey", "format", "quoting", "this"] 
=> ["this"] 
> intersection.empty? 
=> false 
+0

Me encanta este enfoque para la verificación de una sola palabra (por ejemplo, 'hey'). Sin embargo, las cosas se desmoronan si necesita una verificación de frase (por ejemplo, 'hey you'). –

15

La forma más sencilla que conozco para poner a prueba para la inclusión de una cadena dentro de otra es:

text = 'this is the line' 
words = ['hey', 'format', 'qouting', 'this'] 

words.any? { |w| text[w] } #=> true 

n necesidad de expresiones regulares, o algo complicado.

require 'benchmark' 

n = 200_000 
Benchmark.bm(3) do |x| 
    x.report("1:") { n.times { words.any? { |w| text =~ /#{w}/ } } } 
    x.report("2:") { n.times { text.split(" ").find { |item| words.include? item } } } 
    x.report("3:") { n.times { text.split(' ') & words } } 
    x.report("4:") { n.times { words.any? { |w| text[w] } } } 
    x.report("5:") { n.times { words.any? { |w| text.include?(w) } } } 
end 

>>   user  system  total  real 
>> 1: 4.170000 0.160000 4.330000 ( 4.495925) 
>> 2: 0.500000 0.010000 0.510000 ( 0.567667) 
>> 3: 0.780000 0.030000 0.810000 ( 0.869931) 
>> 4: 0.480000 0.020000 0.500000 ( 0.534697) 
>> 5: 0.390000 0.010000 0.400000 ( 0.476251) 
+1

o use 'include?' Para ser más legible ('text.include? W') – rubyprince

+0

No encuentro' include? 'Para ser más legible que' text [w] '. Aunque es un poco más rápido. –

+4

'text.include? w' sugiere que devuelve un valor booleano si 'w' está incluido en' text'. 'text [w]' a primera vista puede interpretarse como que da el valor inicial de 'w' en' text'. – rubyprince

Cuestiones relacionadas