Spanish [SOLUCIONADO] ¿Cómo se puede comparar el "contenido" de dos cadenas?

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Muy buenas, necesito saber si el contenido de una cadena es mayor que el contenido de otra. NO las longitudes, ni si son distintas que ya más o menos lo tengo controlado.

B4X:
Dim A = "Ver. 01" As String
Dim B = "Ver. 02" As String
If A > B Then 
  Log(" A Mayor B")
  Else
  Log ("A No mayor que B") 
End If


El error que sale en el log:
B4X:
main_activity_create (java line: 453)
java.lang.NumberFormatException: Invalid double: "Ver. 01"
    at java.lang.StringToReal.invalidReal(StringToReal.java:63)
    at java.lang.StringToReal.initialParse(StringToReal.java:114)
    at java.lang.StringToReal.parseDouble(StringToReal.java:282)
    at java.lang.Double.parseDouble(Double.java:301)
    at b4a.epai.fichajes.main._activity_create(main.java:453)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
    at b4a.epai.fichajes.main.afterFirstLayout(main.java:102)
    at b4a.epai.fichajes.main.access$000(main.java:17)
    at b4a.epai.fichajes.main$WaitForLayout.run(main.java:80)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:158)
    at android.app.ActivityThread.main(ActivityThread.java:7225)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Siento lo "absurdo" de la pregunta pero llevo un buen rato buscando posibilidades y no encuentro como.

Gracias..
 

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
En este caso para saber si tengo que avisar de que hay una nueva versión disponible.

Pero en otro momento será para otra cosa. Una simple comparación de cadenas.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Gabino, el error te sale por que no puedes comparar asi dos string, tines que poner la versión en un entero y entonces la comparación seria correcta:

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hay muchas formas de hacerlo, esta podria ser una:

B4X:
Dim NumVersion1, NumVersion2 as Int
Dim TxtVersion=  "Ver. " as String

If NumVersion1 > NumVersion2 Then 
  Log(" NumVersion1 Mayor NumVersion2")
  Log("La Versión mayor es: " & TxtVersion & NumVersion1
Else
  Log ("NumVersion1 No mayor que NumVersion2") 
  Log("La Versión menor es: " & TxtVersion & NumVersion2
EndIf

Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola

En este caso para saber si tengo que avisar de que hay una nueva versión disponible.

Supongo que sabrás que puedes saber la versión con la libreria Phone pasandole el nombre del paquete (no del apk).

B4X:
    Dim pm As PackageManager ' libreria Phone
    Try
      VersionAplicacion = pm.GetVersionName(NombrePaquete)
    Catch
       Log(LastException)
    End Try

Saludos

Hay también una forma de saber si existe en Google Play una versión mas actual que la que estas, pero si es eso lo que necesitas, mejor abre un nuevo hilo y así podrá saber la solución mas gente, por que con el nombre de este post no lo podrian averiguar

Saludos
 

dar2o3

Active Member
Licensed User
Longtime User
Aparte de lo ya dicho por el compañero @bgsoft si te hace falta ordenar cadenas de texto, puedes meterlas en una lista y ordenas la lista.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Gabino, se me olvidó lo mas importante, tu pregunta inicial :rolleyes:

Puedes emplear esta instrucción:

B4X:
CompareTo (OtroString As String) As Int
Pero cuidado, la comparación que hace es lexicográfica:
Devuelve un valor inferior a 0 si la cadena actual precede a OtroString.
Devuelve 0 si ambas cadenas son iguales.
Devuelve un valor mayor que 0 si la cadena actual se produce después de OtroString.
Ten en cuenta que los caracteres en mayúsculas preceden a los caracteres en minúscula.

B4X:
"abc".CompareTo("da") ' < 0
"abc".CompareTo("Abc") ' > 0
"abc".CompareTo("abca")' < 0



Saludos
 
Last edited:

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Ante todo, muchas gracias a los dos por vuestras respuestas.

La verdad es que inicialmente había utilizado un campo float para poder tener diferentes "revisiones" dentro de la misma versión. Pero al trazar me di cuenta que en determinados número añadía un montón de decimales con lo cual tampoco me fiaba de que la comparación fuera a funcionar siempre.

Lo de los enteros también lo había pensado pero empezar por la versión 100 en lugar de por la 1.00 tampoco me gustaba demasiado.

Así que finalmente me decidí a trabajar con las strings pensando que me me iban a solucionar el problema. Pero ya veo que ni para nada.

Sigo sin entender muy bien porque es tan complicado hacer un > o < tratándose de cadenas...

Como siempre van a ser xx.yy, tendré que coger la parte de la izquierda del punto y convertirla a número, multiplicarla por 100 y sumarle la parte de la derecha pasada a número también.

O mirar lo de ordenar la lista. Quizás me haga una función... Gracias de nuevo a ambos.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
O mirar lo de ordenar la lista. Quizás me haga una función... Gracias de nuevo a ambos.

Tus deseos son ordenes ;) , aprovechando una cosa "rara" de Android te hago una función facil, ponle los valores que quieras, puedes hacer que sea un Boolean y considerar solo cuando una de ellas es mayor ponerlo a True, esto tu mismo, te lo he echo asi para que se vea facil.
Tambien puedes hacer que te devuelva un string y devolver la que es mayor

B4X:
Dim V1, V2 As String

V1 = "1.51"
V2 = "1.6"
 
Log("Comparar Versiones " & CompararVersiones(V1,V2))


' Devuelve: 0 = , 1 >  2>
Sub CompararVersiones(TxtVersion1 As String , TxtVersion2 As String) As Int
    
   Dim V1, V2 As Double  ' la clave del exito ;-)
 
   V1 = TxtVersion1
   V2 = TxtVersion2
 
   If V1 = V2 Then
     Log("Iguales")
     Return 0
   End If
 
   If V1 > V2 Then
     Log("Primero Mayor")
     Return 1
   Else
     Log("Segundo Mayor") 
     Return 2
   End If

 
End Sub

Saludos
 

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Supongo que lo más correcto sería trabajar con las versiones en números enteros (aunque no me gusten demasiado). Pero al final me he decantado por la función para no tener que andar haciendo demasiados cambios tanto en la parte del cliente como en la del servidor. Sobre todo por que es algo que ya tengo en "producción".

Con esta función creo me voy a arreglar y la publico para si alguien más se ven en la necesidad de comparar dos "simples" cadenas:

B4X:
' Compara dos cadenas y dice si la primera cadena es ">", "=" ó "<" que la segunda
' Ej. ComparaCadenas("001", "002) devolvería "<"
Sub ComparaCadenas(Cadena1 As String, Cadena2 As String) As String
    If Cadena1.EqualsIgnoreCase(Cadena2) Then
            Return "="
        Else
            Dim lista As List
            lista.Initialize2(Array As String(Cadena1, Cadena2))
            lista.Sort(True)
            If lista.IndexOf(Cadena1) = 0 Then 
                Return "<"
             Else
                Return ">"
            End If
    End If
End Sub
 

bgsoft

Well-Known Member
Licensed User
Longtime User

Gabino A. de la Gala

Active Member
Licensed User
Longtime User
Si, por poco :), pero al menos así los compañeros tendran dos versiones que siempre va bien

Saludos
Pues sí.
  1. La tuya para "solo" números es mejor que la mía ya que no hay que andar justificando con 0's a la izquierda.
  2. La mía es mejor que la tuya porque vale para comparar "strings"
Que cada cual se sirva con la que más se adapte a sus necesidades. ;)
 
Top