De esa manera, no terminará creando una nueva matriz en cada llamada. La cadena también es más fácil de escanear que una serie de caracteres literales, en mi opinión.
Por supuesto, si solo va a usar esto una vez, para que la creación desperdiciada no sea un problema, puede usar:
Realmente depende de cuál le resulte más legible, si desea utilizar los caracteres de puntuación en otro lugar y con qué frecuencia se llamará al método.
EDITAR: Aquí hay una alternativa al método de Reed Copsey para averiguar si una cadena contiene exactamente uno de los caracteres.
privatestaticreadonlyHashSet<char>Punctuation=newHashSet<char>("*&#...");publicstaticboolContainsOnePunctuationMark(string text){bool seenOne =false;foreach(char c in text){// TODO: Experiment to see whether HashSet is really faster than// Array.Contains. If all the punctuation is ASCII, there are other// alternatives...if(Punctuation.Contains(c)){if(seenOne){returnfalse;// This is the second punctuation character}
seenOne =true;}}return seenOne;}
Supongo que vale la pena almacenar en caché la matriz de caracteres si el rendimiento es un problema, pero, de nuevo, es posible que no valga la pena según el contexto.
Noldorin
1
Sí, si solo lo está usando en un método que se ejecutará una vez, puede que no valga la pena. Sin embargo, creo que mejora la legibilidad y el rendimiento. Por ToCharArraysupuesto, puede utilizar el formulario "en línea" si es necesario.
Jon Skeet
1
@canon: ¿Qué tan grande es el set? Para conjuntos muy, muy pequeños, esperaría que Array.Contains sea más rápido. Para conjuntos grandes, es probable que HashSet gane por millas.
Jon Skeet
5
Si solo desea ver si contiene algún carácter, le recomiendo usar string.IndexOfAny, como se sugiere en otra parte.
Si desea verificar que una cadena contiene exactamente uno de los diez caracteres, y solo uno, entonces se vuelve un poco más complicado. Creo que la forma más rápida sería verificar una intersección y luego verificar si hay duplicados.
privatestaticchar[] characters =newchar[]{'*','&',...};publicstaticboolContainsOneCharacter(string text){var intersection = text.Intersect(characters).ToList();if( intersection.Count!=1)returnfalse;// Make sure there is only one character in the text// Get a count of all of the one found characterif(1== text.Count(t => t == intersection[0]))returntrue;returnfalse;}
Sí, supongo que un solo bucle es probablemente más rápido en este caso, especialmente con el pequeño conjunto de puntuación. Tendría curiosidad por probar esto con cadenas grandes para ver cuál es realmente más rápido.
Reed Copsey
1
Creo que encontrar la intersección de las dos cadenas tendrá que ir carácter por carácter de todos modos, así que no puedo ver cómo sería más rápido ... y mi ruta sugerida no solo usa una sola pasada, sino que también tiene la opción de "salida anticipada". Imagínese si el texto tiene un millón de caracteres, pero los dos primeros son "*" :)
var specialChars =new[]{'\\','/',':','*','<','>','|','#','{','}','%','~','&'};foreach(var specialChar in specialChars.Where(str.Contains)){Console.Write(string.Format("string must not contain {0}", specialChar));}
ya que estaba buscando una buena manera de detectar si una determinada cadena era en realidad un precio o una oración, como 'Demasiado bajo para mostrar'.
Sé que esto es antiguo, pero para que quede claro, esta no es una forma particularmente buena de hacer coincidir las monedas ... Si alguien escribiera "Ke $ ha", coincidiría como precio ... En su lugar, consulte una forma adecuada de detectar la moneda definida aquí: stackoverflow.com/questions/7214513/…
Respuestas:
El siguiente sería el método más simple, en mi opinión:
O en una forma posiblemente más fácil de leer:
Según el contexto y el rendimiento requeridos, es posible que desee o no almacenar en caché la matriz de caracteres.
fuente
Como han dicho otros, use IndexOfAny. Sin embargo, lo usaría de esta manera:
De esa manera, no terminará creando una nueva matriz en cada llamada. La cadena también es más fácil de escanear que una serie de caracteres literales, en mi opinión.
Por supuesto, si solo va a usar esto una vez, para que la creación desperdiciada no sea un problema, puede usar:
o
Realmente depende de cuál le resulte más legible, si desea utilizar los caracteres de puntuación en otro lugar y con qué frecuencia se llamará al método.
EDITAR: Aquí hay una alternativa al método de Reed Copsey para averiguar si una cadena contiene exactamente uno de los caracteres.
fuente
ToCharArray
supuesto, puede utilizar el formulario "en línea" si es necesario.Si solo desea ver si contiene algún carácter, le recomiendo usar string.IndexOfAny, como se sugiere en otra parte.
Si desea verificar que una cadena contiene exactamente uno de los diez caracteres, y solo uno, entonces se vuelve un poco más complicado. Creo que la forma más rápida sería verificar una intersección y luego verificar si hay duplicados.
fuente
Aquí está la documentación de Microsoft .
fuente
fuente
¡Gracias a todos ustedes! (¡Y principalmente Jon!): Esto me permitió escribir esto:
ya que estaba buscando una buena manera de detectar si una determinada cadena era en realidad un precio o una oración, como 'Demasiado bajo para mostrar'.
fuente