elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Sigue las noticias más importantes de seguridad informática en el Twitter! de elhacker.NET


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación General
| | |-+  .NET (C#, VB.NET, ASP) (Moderador: kub0x)
| | | |-+  Obtener el índice de un elemento obtenido con Split
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Obtener el índice de un elemento obtenido con Split  (Leído 2,520 veces)
okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
Obtener el índice de un elemento obtenido con Split
« en: 7 Diciembre 2016, 20:41 pm »

Quiero obtener el índice de un elemento obtenido con Split utilizando IndexOf pero no lo consigo.

Si hago esto:

Código
  1. Dim P As String() = {"[Primero]", "a", "b", "c", "[Segundo]"}
  2.        MessageBox.Show(CStr(P.ToList.IndexOf("[Segundo]")))

Me devuelve el índice correctamente.


Si hago esto otro:
Código
  1. Dim P As New List(Of String)
  2.        P.AddRange({"[Primero]", "a", "b", "c", "[Segundo]"})
  3.        MessageBox.Show(CStr(P.IndexOf("[Segundo]")))

También me devuelve el índice correctamente

Sin embargo con un array obtenido con Split no funciona, me devuelve -1.


Código
  1.  
  2.  
  3. Dim Texto As String =
  4.               "[Primero]" & Environment.NewLine &
  5.               "a" & Environment.NewLine &
  6.               "b" & Environment.NewLine &
  7.               "c" & Environment.NewLine &
  8.               "[Segundo]"
  9.  
  10.        Dim P As New List(Of String)
  11.        P.AddRange((Texto.ToString.Trim.Split(CChar(Environment.NewLine))))
  12.  
  13.        MessageBox.Show(CStr(P.IndexOf("[Segundo]")))
  14.        MessageBox.Show(CStr(P(4)))


No acabo de entender porqué si al llamarlo con P(4), si que me devuelve el valor. O sea que el elemento está en la lista P, sin embargo no me devuelve el índice.

Gracias



Conseguí hacerlo:

Código
  1.        Dim Texto As String =
  2.               "[Primero]" & Environment.NewLine &
  3.               "a" & Environment.NewLine &
  4.               "b" & Environment.NewLine &
  5.               "c" & Environment.NewLine &
  6.               "[Segundo]"
  7.  
  8.        Dim spl() As String = Texto.Split(CChar(Environment.NewLine))
  9.        Dim Lista As New List(Of String)
  10.        For Each Item As String In spl
  11.                Lista.Add(Item.Trim)
  12.        Next
  13.  
  14.        MessageBox.Show(Lista.IndexOf("[Segundo]").ToString)

Pero sigo si entender porque no puedo obtenerlo directamente como puse antes o usando directamente el array String:

Código
  1. Dim spl() As String = Texto.Split(CChar(Environment.NewLine))
  2.        MessageBox.Show(spl.ToList.IndexOf("[Segundo]").ToString)

Parece que Split devuelve los valores con espacios, de ahí que haya añadido Trim, para eliminar los caracteres de espacio.

Si lo pusiera así:

Código
  1.  
  2. ...
  3. For Each Item As String In spl
  4.            Lista.Add(Item)
  5.        Next
  6.        MessageBox.Show(Lista.IndexOf("[Segundo]").ToString)
  7.  
me devolvería -1 nuevamente.



Encontré otra solución para quien le sirva. Consiste en reemplazar el espacio de cada elemento, sin necesidad de crear otro array

Código
  1.         Dim Texto As String =
  2.             "[Primero]" & Environment.NewLine &
  3.             "a" & Environment.NewLine &
  4.             "b" & Environment.NewLine &
  5.             "c" & Environment.NewLine &
  6.             "[Segundo]"
  7.  
  8.        Dim spl() As String = Texto.Split(CChar(Environment.NewLine))
  9.        For Index As Integer = 0 To spl.Count - 1
  10.            spl(Index) = spl(Index).Trim
  11.        Next
  12.        MessageBox.Show(spl.ToList.IndexOf("[Segundo]").ToString)


Lo suyo sería poder hacerlo todo en la misma línea, en esta:
Código
  1. Dim spl() As String = Texto.Split(CChar(Environment.NewLine))



Vale, pues este sería otro modo más reducido. Usando  Regex
Código
  1.        Dim Texto As String =
  2.             "[Primero]" & Environment.NewLine &
  3.             "a" & Environment.NewLine &
  4.             "b" & Environment.NewLine &
  5.             "c" & Environment.NewLine &
  6.             "[Segundo]"
  7.        Dim spl() As String = System.Text.RegularExpressions.Regex.Split(Texto, Environment.NewLine)
  8.        MessageBox.Show(spl.ToList.IndexOf("[Segundo]").ToString)






« Última modificación: 7 Diciembre 2016, 22:16 pm por okik » En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: Obtener el índice de un elemento obtenido con Split
« Respuesta #1 en: 9 Diciembre 2016, 19:41 pm »

Sin embargo con un array obtenido con Split no funciona, me devuelve -1.
Código
  1.        Dim Texto As String =
  2.               "[Primero]" & Environment.NewLine &
  3.               "a" & Environment.NewLine &
  4.               "b" & Environment.NewLine &
  5.               "c" & Environment.NewLine &
  6.               "[Segundo]"
  7.  
  8.        Dim P As New List(Of String)
  9.        P.AddRange((Texto.ToString.Trim.Split(CChar(Environment.NewLine))))
  10.  
  11.        MessageBox.Show(CStr(P.IndexOf("[Segundo]")))
  12.        MessageBox.Show(CStr(P(4)))

No acabo de entender porqué si al llamarlo con P(4), si que me devuelve el valor.

No te funciona por que el texto que buscas y el que crees que devuelve el índice 4 no es "[Segundo]", sino LINEA VACÍA + "[Segundo]", es decir, lo que haces de forma incorrecta es partir la cadena de texto, puesto que estás añadiendo lineas en blanco, no tiene más misterio ...todas esas soluciones que encontraste usando RegEx y etc. son innecesarias, puesto que el único fallo que tuviste fue no darte cuenta de cual era el problema real.

La solución es muy sencilla, puedes utilizar el overload de la función String.Split() en donde puedes especificar el parámetro StringSplitOptions para eliminar lineas en blanco sobrantes:

Código
  1. P.AddRange((Texto.Split({ControlChars.NewLine}, StringSplitOptions.RemoveEmptyEntries)))

Te dejo el ejemplo completo (usando la sintaxis compatible con VB 14):
Código
  1. Dim str As String =
  2. "[Primero]
  3. a
  4. b
  5. c
  6. [Segundo]"
  7.  
  8. Dim strList As New List(Of String)
  9. strList.AddRange((str.Split({ControlChars.CrLf}, StringSplitOptions.RemoveEmptyEntries)))
  10.  
  11. MessageBox.Show(CStr(strList.IndexOf("[Segundo]")))
  12. MessageBox.Show(String.Format("""{0}""", strList(4)))

Saludos!


« Última modificación: 9 Diciembre 2016, 21:07 pm por Eleкtro » En línea



okik


Desconectado Desconectado

Mensajes: 462


Ver Perfil
Re: Obtener el índice de un elemento obtenido con Split
« Respuesta #2 en: 10 Diciembre 2016, 19:16 pm »

Genial @Elektro, pues no tenía ni idea de StringSplitOptions.RemoveEmptyEntries y mira que estuve mirando a ver si había algo pero nada.

Pues ya me lo apunto y le quito el regex al programa que estaba haciendo..



Ya no hace falta que añada el list

Código
  1.        Dim Texto As String =
  2.           "[Primero]" & Environment.NewLine &
  3.           "a" & Environment.NewLine &
  4.           "b" & Environment.NewLine &
  5.           "c" & Environment.NewLine &
  6.           "[Segundo]"
  7.        Dim spl() As String = Texto.Split({Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries)
  8.        MessageBox.Show(spl.ToList.IndexOf("[Segundo]").ToString)


No encontraba la forma porque la clave está en ponerlo entre corchetes {Environment.NewLine}, entonces la función Split si que ya te ofrece la opción de añadir StringSplitOptions
« Última modificación: 10 Diciembre 2016, 19:29 pm por okik » En línea

Eleкtro
Ex-Staff
*
Conectado Conectado

Mensajes: 9.878



Ver Perfil
Re: Obtener el índice de un elemento obtenido con Split
« Respuesta #3 en: 10 Diciembre 2016, 21:09 pm »

la clave está en ponerlo entre corchetes {Environment.NewLine}, entonces la función Split si que ya te ofrece la opción de añadir StringSplitOptions

Sé que este tema ya ha quedado solucionado pero me gustaría comentarte algo que podría serte de utilidad en el futuro.

Efectivamente ese overload solo acepta un {Array} de caracteres y/o de strings, no acepta un string individual, yo por eso utilizo las siguientes extensiones (ATENCIÓN, PROPAGANDA GRATUITA :xD) que puedes encontrar en mi set de librerías ElektroKit para acomodar diferentes situaciones de uso en la vida real:

Código
  1. ''' <summary>
  2. ''' Contains custom extension methods to use with the <see cref="System.String"/> type.
  3. ''' </summary>
  4. <ImmutableObject(True)>
  5. <HideModuleName>
  6. Public Module StringExtensions
  7.  
  8.        ''' <summary>
  9.        ''' Splits a string into substrings that are based on the specified string.
  10.        ''' </summary>
  11.        <DebuggerStepThrough>
  12.        <Extension>
  13.        <EditorBrowsable(EditorBrowsableState.Always)>
  14.        Public Function Split(ByVal sender As String,
  15.                              ByVal separator As String,
  16.                              ByVal options As StringSplitOptions) As String()
  17.  
  18.            Return sender.Split({separator}, options)
  19.  
  20.        End Function
  21.  
  22.        ''' <summary>
  23.        ''' Splits a string into a maximum number of substrings based on the specified string.
  24.        ''' </summary>
  25.        <DebuggerStepThrough>
  26.        <Extension>
  27.        <EditorBrowsable(EditorBrowsableState.Always)>
  28.        Public Function Split(ByVal sender As String,
  29.                              ByVal separator As String,
  30.                              ByVal count As Integer,
  31.                              ByVal options As StringSplitOptions) As String()
  32.  
  33.            Return sender.Split({separator}, count, options)
  34.  
  35.        End Function
  36.  
  37. End Module

Lo puedes copiar y pegar y listo (o puedes ignorar lo que te digo xD), siempre viene bien tener utensilios así a mano. En el código he eliminado toda la documentación adicional (que es mucha) de los parámetros y etc. para que no se haga tediosa la lectura.

Como puedes ver, esas funciones no hacen nada más lejos que llamar a las funciones originales de .NET Framework pero pasando el string como array (así que no hay que preocuparse por un error humano por mi parte).

Ejemplo de uso:
Código
  1. Dim str As String = "Hello" & Environment.NewLine & "World"
  2. Dim arr As String() = str.Split(ControlChars.NewLine, StringSplitOptions.RemoveEmptyEntries)
  3.  
  4. For Each item As String In arr
  5.    Console.WriteLine(item)
  6. Next

y:

Código
  1. Dim str As String = "Hello" & Environment.NewLine & Environment.NewLine & "World"
  2. Dim arr As String() = str.Split(ControlChars.NewLine, 3, StringSplitOptions.None)
  3.  
  4. For Each item As String In arr
  5.    Console.WriteLine(item)
  6. Next

¡Un saludo!
« Última modificación: 10 Diciembre 2016, 21:15 pm por Eleкtro » En línea



Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
detectar item de lista con doble click y obtener id de elemento
Programación C/C++
dewolo 7 4,806 Último mensaje 4 Octubre 2011, 22:57 pm
por Eternal Idol
Obtener valor de un elemento html
Desarrollo Web
itzg3 4 4,295 Último mensaje 7 Abril 2014, 22:18 pm
por itzg3
Obtener texto de un elemento de una web
.NET (C#, VB.NET, ASP)
j0lama 1 3,446 Último mensaje 2 Febrero 2015, 02:12 am
por Eleкtro
¿Como obtener una combinacion mediante su indice?
Scripting
Yidu 9 4,757 Último mensaje 19 Julio 2015, 12:02 pm
por Yidu
como obtener la id de un elemento
Programación Visual Basic
vargas14 0 1,801 Último mensaje 27 Julio 2016, 21:40 pm
por vargas14
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines