IndexOf
, IndexOfAny
y LastIndexOf
, LastIndexOfAny
no se parecen a hacer éstos (o tal vez lo hacen). Estoy buscando el equialent de std :: string's find_first_not_of
y find_last_not_of
. Estoy pensando en crear una clase de extensión, pero no estoy seguro si C# ya proporciona esta funcionalidad.C# equivalente de C++ find_first_not_of std :: string y find_last_not_of
Respuesta
string source = "the quick brown fox jumps over the lazy dog";
string chars = "ogd hte";
int? firstNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
.Where(x => chars.IndexOf(x.Val) == -1)
.Select(x => x.Idx)
.FirstOrDefault();
int? lastNotOf = source.Select((x, i) => new { Val = x, Idx = (int?)i })
.Where(x => chars.IndexOf(x.Val) == -1)
.Select(x => x.Idx)
.LastOrDefault();
O, si lo prefiere algunos métodos de extensión no LINQ. Estos deben tener un rendimiento ligeramente mejor, especialmente para FindLastNotOf
:
int? firstNotOf = source.FindFirstNotOf(chars);
int? lastNotof = source.FindLastNotOf(chars);
// ...
public static int? FindFirstNotOf(this string source, string chars)
{
if (source == null) throw new ArgumentNullException("source");
if (chars == null) throw new ArgumentNullException("chars");
if (source.Length == 0) return null;
if (chars.Length == 0) return 0;
for (int i = 0; i < source.Length; i++)
{
if (chars.IndexOf(source[i]) == -1) return i;
}
return null;
}
public static int? FindLastNotOf(this string source, string chars)
{
if (source == null) throw new ArgumentNullException("source");
if (chars == null) throw new ArgumentNullException("chars");
if (source.Length == 0) return null;
if (chars.Length == 0) return source.Length - 1;
for (int i = source.Length - 1; i >= 0; i--)
{
if (chars.IndexOf(source[i]) == -1) return i;
}
return null;
}
(Es posible que usted podría obtener un mejor rendimiento - tanto en el LINQ y las versiones no-LINQ - si convierte chars
a un HashSet<char>
, o tal vez incluso una llanura char[]
matriz. que había necesidad de referencia para averiguar, a pesar de cualquier diferencia es probable que sea insignificante a menos chars
pone bastante grande.)
Si el uso de LINQ es aceptable, puede llamar a los métodos First() y Last() con el predicado apropiado.
Por ejemplo, si desea que los primeros y últimos caracteres que no son vocales:
string vowels = "aeiouy";
char first = yourString.First(ch => vowels.IndexOf(ch) < 0);
char last = yourString.Last(ch => vowels.IndexOf(ch) < 0);
EDIT: El anterior devolverá los caracteres, no sus índices. Con el fin de hacer eso, se puede proyectar los índices utilizando el método Select(), pero las cosas se ponen peludas, ya que necesitamos para volver -1
si ningún carácter coincide:
int firstIndex = (yourString.Select(
(ch, i) => new { Character = ch, Index = i }
).First(obj => vowels.IndexOf(obj.Character) < 0)
?? new { Character = '\0', Index = -1 }).Index;
int lastIndex = (yourString.Select(
(ch, i) => new { Character = ch, Index = i }
).Last(obj => vowels.IndexOf(obj.Character) < 0)
?? new { Character = '\0', Index = -1 }).Index;
Alternativamente, he aquí una solución menos complicada basado en @ abatishchev de contestar:
string vowels = "aeiouy";
int firstIndex = yourString.IndexOf(yourString.First(
ch => vowels.IndexOf(ch) < 0));
int lastIndex = yourString.LastIndexOf(yourString.Last(
ch => vowels.IndexOf(ch) < 0));
no exactamente: 'find_first_not_of' devuelve la posición, no el carácter. – Vlad
@Vlad, tienes razón, la respuesta se actualizó en consecuencia. Gracias :) –
Creo que LINQ complica mucho las cosas. Y esta solución es muy ineficaz. Estamos creando una gran cantidad de objetos temporales de tipo anónimo junto con iteradores. El método de escritura que simplifica el ciclo será mejor. –
he aquí una solución expresión regular.
string testString = "oueytestie";
var matchFirstNotOf = Regex.Match(testString, @"[^aeiouy]");
int firstNotOf = matchFirstNotOf.Success ? matchFirstNotOf.Index : -1;
var matchLastNotOf = Regex.Match(testString, @"[^aeiouy]", RegexOptions.RightToLeft);
int lastNotOf = matchLastNotOf.Success ? matchLastNotOf.Index : -1;
- 1. Cython C++ y std :: string
- 2. C++ std :: string y NULL const char *
- 3. Unicode y std :: string en C++
- 4. C++ std :: string to boolean
- 5. Eliminar espacios de std :: string en C++
- 6. Obtenga bytes de std :: string en C++
- 7. C++/CLI La conversión de Sistema :: string^std :: string
- 8. Convertir flotador para std :: string en C++
- 9. ¿Están C++ std :: map <string, string> ordenados?
- 10. Cómo eliminar acentos y tilde en C++ std :: string
- 11. C++ .NET convert System :: String to std :: string
- 12. ¿C# tiene un equivalente std :: nth_element?
- 13. ¿Cómo puedo tomar posesión de un C++ std :: string char data sin copiar y mantener el objeto std :: string?
- 14. Comparación de Literal de carácter a Std :: String en C++
- 15. C++ std :: pair, std :: vector y memcopy
- 16. std :: string :: longitud() vs. std :: string :: size()
- 17. C++ String Variable Declaration
- 18. SWIG: Cómo ajustar std :: string & (std :: string pasado por referencia)
- 19. Definir std :: string en C++ sin caracteres de escape
- 20. C# string manipulación buscar y reemplazar
- 21. std :: vector <std::string> crash
- 22. Rendimiento std :: strstr vs std :: string :: encontrar
- 23. Will std :: string siempre tendrá terminación nula en C++ 11?
- 24. Lea todo el archivo ASCII en C++ std :: string
- 25. C++ copy std :: string a char array sin terminación nula
- 26. ¿Hay un equivalente de std :: set en C#?
- 27. Cómo convertir std :: string a LPCWSTR en C++ (Unicode)
- 28. Cómo convertir caracteres sin signo * a std :: string en C++?
- 29. C++ String declarando
- 30. Python equivalente a std :: set y std :: multimap
Buen trabajo, pero ¿quién en su sano juicio encuentra algo aceptable en una biblioteca o rutina de API? Parece que un MS falla. – GTAE86