Hay una manera mejor de hacer esto…

MyString.Trim().Replace("&", "and").Replace(",", "").Replace("  ", " ")
         .Replace(" ", "-").Replace("'", "").Replace("/", "").ToLower();

He extendido la clase string para mantener a un trabajo, pero hay una forma más rápida?

public static class StringExtension
{
    public static string clean(this string s)
    {
        return s.Replace("&", "and").Replace(",", "").Replace("  ", " ")
                .Replace(" ", "-").Replace("'", "").Replace(".", "")
                .Replace("eacute;", "é").ToLower();
    }
}

Sólo por diversión (y para detener los argumentos en los comentarios)
He metió una idea hasta la evaluación comparativa de los diversos ejemplos a continuación.

https://gist.github.com/ChrisMcKee/5937656

La opción regex puntuaciones terriblemente; el diccionario opción es la más rápida; el largo aliento de la versión de la stringbuilder reemplazar es ligeramente más rápido que el corto de la mano.

  • Basado en lo que usted tiene en sus puntos de referencia parece que el diccionario de la versión no está haciendo todos los reemplazos que sospecho que es lo que está haciendo que sea más rápido que el StringBuilder soluciones.
  • Hola de 2009; he añadido un comentario a continuación en abril sobre ese garrafal error. La esencia se actualiza a pesar de que me he saltado sobre D. El diccionario de la versión es todavía más rápido.
  • Posibles duplicados de Alternativa a la Cadena.Reemplazar varias veces?
  • al menos, comprobar las fechas antes de marcar las cosas; esto es a partir de 2009 a eso de 2012
InformationsquelleAutor Chris McKee | 2009-08-24

8 Comentarios

  1. 105

    Más rápido – no. Más eficaz – sí, si va a utilizar el StringBuilder clase. Con la implementación de cada operación genera una copia de una cadena que bajo circunstancias puede perjudicar el rendimiento. Las cadenas son inmutable objetos para cada operación sólo devuelve una copia modificada.

    Si esperas que este método se implicó activamente en múltiples Strings de considerable longitud, podría ser mejor para «migrar» su implementación en el StringBuilder clase. Cualquier modificación se realiza directamente en esa instancia, por lo que sobra innecesarias las operaciones de copia.

    public static class StringExtention
    {
        public static string clean(this string s)
        {
            StringBuilder sb = new StringBuilder (s);
    
            sb.Replace("&", "and");
            sb.Replace(",", "");
            sb.Replace("  ", " ");
            sb.Replace(" ", "-");
            sb.Replace("'", "");
            sb.Replace(".", "");
            sb.Replace("eacute;", "é");
    
            return sb.ToString().ToLower();
        }
    }
    • Para mayor claridad el diccionario respuesta es la forma más rápida stackoverflow.com/a/1321366/52912
    • En su punto de referencia en gist.github.com/ChrisMcKee/5937656 el diccionario de la prueba no es completa: no todos los reemplazos y «»sustituye» a «, no » «. No hacer todos los reemplazos podría ser la razón, por qué es más rápido en el punto de referencia. La expresión regular que la sustitución no es completa, ya sea. Pero lo más importante de su cadena de TestData es es corto. Como el aceptado la respuesta de los estados, la cadena ser de gran longitud para el StringBuilder a ser una ventaja. Podría usted por favor, repita el punto de referencia con las cadenas de 10kB, 100 kb y 1 mb?
    • Es un buen punto; tal y como está, que estaba siendo utilizado para la url de limpieza para la prueba en 100kb – 1mb habría sido realista. Voy a actualizar la referencia, por lo que su uso de la totalidad de la cosa, aunque, eso fue un error.
  2. 13

    Tal vez un poco más legible?

        public static class StringExtension {
    
            private static Dictionary<string, string> _replacements = new Dictionary<string, string>();
    
            static StringExtension() {
                _replacements["&"] = "and";
                _replacements[","] = "";
                _replacements["  "] = " ";
                //etc...
            }
    
            public static string clean(this string s) {
                foreach (string to_replace in _replacements.Keys) {
                    s = s.Replace(to_replace, _replacements[to_replace]);
                }
                return s;
            }
        }

    También agregar Nuevos En la Ciudad sugerencia acerca de StringBuilder…

    • Sería más legible como este: private static Dictionary<string, string> _replacements = new Dictionary<string, string>() { {"&", "and"}, {",", ""}, {" ", " "} /* etc */ };
    • o, por supuesto… private static readonly Diccionario<string, string> los Reemplazos = new Dictionary<string, string>() { { «&», «y» }, { «,», «» }, { » «, «» } /* etc */ }; public static string Limpio(esto string s) { return Reemplazos.Teclas.Agregado(s, (actual, toReplace) => actual.Reemplazar(toReplace, Reemplazos[toReplace])); }
    • -1 : el Uso de un Diccionario doesen no hacer ningún sence aquí. Sólo tiene que utilizar un List<Tuple<string,string>>. Esto también cambia el orden de los replacings Y no es tan rápida como por ejemplo,s.Replace("a").Replace("b").Replace("c"). No utilice este!
  3. 11

    Si son simplemente después de una solución bonita y no es necesario ahorrar unos pocos nanosegundos, ¿LINQ azúcar?

    var input = "test1test2test3";
    var replacements = new Dictionary<string, string> { { "1", "*" }, { "2", "_" }, { "3", "&" } };
    
    var output = replacements.Aggregate(input, (current, replacement) => current.Replace(replacement.Key, replacement.Value));
    • Similar al ejemplo C en el Gist (si se mira de arriba es el más feo de linq declaración está en el comentario)
    • Interesante que definir un funcional de la declaración como «Feo» de una norma procesal.
    • no voy a discutir sobre ello; su mera preferencia. Como usted dice, linq es simplemente azúcar sintáctico; y como me dijo que yo ya había puesto el equivalente a la anterior, el código 🙂
  4. 11

    esto será más eficiente:

    public static class StringExtension
    {
        public static string clean(this string s)
        {
            return new StringBuilder(s)
                  .Replace("&", "and")
                  .Replace(",", "")
                  .Replace("  ", " ")
                  .Replace(" ", "-")
                  .Replace("'", "")
                  .Replace(".", "")
                  .Replace("eacute;", "é")
                  .ToString()
                  .ToLower();
        }
    }
    • Realmente difícil de leer. Estoy seguro de que usted sabe lo que hace, pero un Junior Dev se rasca su cabeza en lo que realmente ocurre. Estoy de acuerdo, yo también busque siempre el shortes de la mano de escribir algo, Pero era sólo para mi propia satisfacción. Otras personas estaban volviendo loco, en el montón de lío.
    • Esto es realmente más lento. BenchmarkOverhead… 13ms StringClean-user151323… 2843ms StringClean-TheVillageIdiot… 2921ms Varía en las repeticiones, pero la respuesta gana gist.github.com/anonymous/5937596
  5. 3

    Otra opción de utilizar linq es

    [TestMethod]
    public void Test()
    {
      var input = "it's worth a lot of money, if you can find a buyer.";
      var expected = "its worth a lot of money if you can find a buyer";
      var removeList = new string[] { ".", ",", "'" };
      var result = input;
    
      removeList.ToList().ForEach(o => result = result.Replace(o, string.Empty));
    
      Assert.AreEqual(expected, result);
    }
    • Usted puede declarar var removeList = new List<string> { /*...*/ };, a continuación, simplemente llame a removeList.ForEach( /*...*/ ); y simplificar el código. Tenga en cuenta también que no es totalmente responder a la pregunta, porque todo encontrado cadenas son reemplazados con String.Empty.
  6. 2

    Yo estoy haciendo algo similar, pero en mi caso estoy haciendo la serialización/De-la serialización así que tengo que ser capaz de ir en ambas direcciones. Creo que utilizando una cadena[][] funciona de manera casi idéntica a la del diccionario, incluyendo la inicialización, pero usted puede ir en otra dirección, volviendo a los sustitutos a sus valores originales, algo que el diccionario que realmente no está configurado para hacer.

    Editar: puede utilizar Dictionary<Key,List<Values>> con el fin de obtener el mismo resultado as string[][]

  7. -1
    string input = "it's worth a lot of money, if you can find a buyer.";
    for (dynamic i = 0, repl = new string[,] { { "'", "''" }, { "money", "$" }, { "find", "locate" } }; i < repl.Length / 2; i++) {
        input = input.Replace(repl[i, 0], repl[i, 1]);
    }
    • Usted debe considerar la adición de un contexto para sus respuestas. Como una breve explicación de lo que está haciendo Y, si es relevante, ¿por qué se escribió la manera que usted lo hizo.

Dejar respuesta

Please enter your comment!
Please enter your name here