PyIn() - Find anything in anything!! 
Replicates the behavior of the Python keyword 'in' which returns true if something is part of something else, meaning that search is possible for:
- characters in strings
- sub-strings in strings
- characters in arrays of characters
- strings of size 1 in arrays of characters
- numbers (double, float, short, int, long) in arrays of numbers (of the same type)
- bytes in arrays of bytes
- objects in arrays of objects
- anything in lists
- anything in maps (as keys)
https://docs.python.org/3/reference/expressions.html (6.10.2. Membership test operations)
Usage:
Snippet:
Test Cases:
Replicates the behavior of the Python keyword 'in' which returns true if something is part of something else, meaning that search is possible for:
- characters in strings
- sub-strings in strings
- characters in arrays of characters
- strings of size 1 in arrays of characters
- numbers (double, float, short, int, long) in arrays of numbers (of the same type)
- bytes in arrays of bytes
- objects in arrays of objects
- anything in lists
- anything in maps (as keys)
https://docs.python.org/3/reference/expressions.html (6.10.2. Membership test operations)
Usage:
B4X:
If PyIn(something, someContainer) Then
'Do Stuff
End If
Snippet:
B4X:
'Returns wheter or not the given object is part of the given container
Sub PyIn(obj As Object, container As Object) As Boolean
'Is NULL part of NULL? Yes it is!
'----------------------------------------------------
If obj == Null And container == Null Then Return True
'----------------------------------------------------
'A non-NULL object may not be part of a NULL one
'----------------------------------------------------
If container == Null Then Return False
'----------------------------------------------------
'Null object workaround
'----------------------------------------------------
Dim oType = "java.lang.Object" As String
If obj <> Null Then oType = GetType(obj)
'----------------------------------------------------
'Make sure that object is not an Array
'----------------------------------------------------
If oType.CharAt(0) == "[" Then Return False
'----------------------------------------------------
Dim cType = GetType(container) As String
Dim isSearchInArray = cType.CharAt(0) == "[" As Boolean
oType = oType.SubString(oType.LastIndexOf(".") + 1).CharAt(0)
If isSearchInArray Then
Dim cFirstChar = cType.CharAt(1) As Char
If cFirstChar == "L" Then
Select cType.CharAt(cType.LastIndexOf(".") + 1)
Case "S"
If oType == "S" Or oType == "C" Then
Dim strObj = obj As String
Dim strCnt() = container As String
For Each str As String In strCnt
If str == strObj Then Return True
Next
End If
Return False
Case "O"
If oType == "O" Then
Dim objCnt() = container As Object
If obj == Null Then
For Each o As Object In objCnt
If o == Null Then Return True
Next
Else
For Each o As Object In objCnt
If o == obj Then Return True
Next
End If
End If
Return False
End Select
Return False
End If
'Allow String in Char() search
'----------------------------------------------------
If oType == "S" _
And oType.Length == 1 _
And cFirstChar == "C" Then
Dim charObj = obj As Char
Dim charCnt() = container As Char
For Each c As Char In charCnt
If c == charObj Then Return True
Next
Return False
End If
'----------------------------------------------------
'Make sure that object is the same type as the Array
'----------------------------------------------------
If oType == "L" Then oType = "J"
If oType <> cFirstChar Then Return False
'----------------------------------------------------
Select oType
Case "B"
Dim byteObj = obj As Byte
Dim byteCnt() = container As Byte
For Each b As Byte In byteCnt
If b == byteObj Then Return True
Next
Case "S"
Dim shortObj = obj As Short
Dim shortCnt() = container As Short
For Each s As Short In shortCnt
If s == shortObj Then Return True
Next
Case "I"
Dim intObj = obj As Int
Dim intCnt() = container As Int
For Each i As Int In intCnt
If i == intObj Then Return True
Next
Case "J"
Dim longObj = obj As Long
Dim longCnt() = container As Long
For Each j As Long In longCnt
If j == longObj Then Return True
Next
Case "F"
Dim floatObj = obj As Float
Dim floatCnt() = container As Float
For Each f As Float In floatCnt
If f == floatObj Then Return True
Next
Case "D"
Dim doubleObj = obj As Double
Dim doubleCnt() = container As Double
For Each d As Double In doubleCnt
If d == doubleObj Then Return True
Next
Case "C"
Dim charObj = obj As Char
Dim charCnt() = container As Char
For Each c As Char In charCnt
If c == charObj Then Return True
Next
End Select
Return False
End If
Select True
Case container Is String
Dim strContainer = container As String
Dim strObj = obj As String
Return (strContainer.IndexOf(strObj) >= 0)
Case container Is List
Dim lst = container As List
Return (lst.IndexOf(obj) >= 0)
Case container Is Map
Dim map = container As Map
Return map.ContainsKey(obj)
End Select
Return False
End Sub
Test Cases:
B4X:
Sub Tests
'Expected output:
' - All tests should return true, meaning the result is as expected.
'Test String in String()
Log("01: " & (True == PyIn("world", Array As String("hello", "world"))))
Log("02: " & (False == PyIn("world", Array As String("hello", "universe"))))
'Test Char in Char()
Dim c As Char = "w"
Log("03: " & (True == PyIn(c, Array As Char("h", "w"))))
Log("04: " & (False == PyIn(c, Array As Char("h", "x"))))
'Test Char in String()
Log("05: " & (True == PyIn(c, Array As String("h", "w"))))
Log("06: " & (False == PyIn(c, Array As String("h", "x"))))
'Test String in Char()
Log("07: " & (True == PyIn("w", Array As Char("h", "w"))))
Log("08: " & (False == PyIn("w", Array As Char("h", "x"))))
'Test Object in Object()
Dim x As Object
Dim y As Object
Dim z As Object = Array As Object(x)
Log("09: " & (True == PyIn(x, z)))
Log("10: " & (False == PyIn(y, z)))
'Test Byte in Byte()
Dim b As Byte = 5
Log("11: " & (True == PyIn(b, Array As Byte(3, 5))))
Log("12: " & (False == PyIn(b, Array As Byte(3, 6))))
'Test Int in Int()
Dim i As Int = 5
Log("13: " & (True == PyIn(i, Array As Int(3, 5))))
Log("14: " & (False == PyIn(i, Array As Int(3, 6))))
'Test Float in Float()
Dim f As Float = 5.0
Log("15: " & (True == PyIn(f, Array As Float(3, 5))))
Log("16: " & (False == PyIn(f, Array As Float(3, 6))))
'Test Double in Double()
Dim d As Double = 5.0
Log("17: " & (True == PyIn(d, Array As Double(3, 5))))
Log("18: " & (False == PyIn(d, Array As Double(3, 6))))
'Test Long in Long()
Dim j As Long = 5
Log("19: " & (True == PyIn(j, Array As Long(3, 5))))
Log("20: " & (False == PyIn(j, Array As Long(3, 6))))
'Test Short in Short()
Dim s As Short = 5
Log("21: " & (True == PyIn(s, Array As Short(3, 5))))
Log("22: " & (False == PyIn(s, Array As Short(3, 6))))
'Test something in String (incomplete number of test cases)
Log("23: " & (True == PyIn(s, "358")))
Log("24: " & (False == PyIn(s, "378")))
'Test something in List (incomplete number of test cases)
Dim lst As List
lst.Initialize
lst.Add(x)
lst.add("5")
lst.add(5)
lst.add(b)
Log("25: " & (True == PyIn(b, lst)))
Log("26: " & (False == PyIn(s, lst)))
lst.add(s)
Log("27: " & (True == PyIn(s, lst)))
'Test something in Map (incomplete number of test cases)
Dim map As Map
map.Initialize
map.Put(j, "long")
Log("28: " & (True == PyIn(j, map)))
Log("29: " & (False == PyIn(d, map)))
map.Put(d, "double")
Log("30: " & (True == PyIn(d, map)))
End Sub
Last edited: