B4J Code Snippet First stab at Functional Map, Reduce and Filter in B4J

First stab at Functional Map, Reduce, and Filter in B4J

Lost of testing and error checking to do, but I think this is a decent starting draft:

B4X:
'// ******************* In Main *******************
Sub AppStart (Form1 As Form, Args() As String)

	Private n_Count = 0
	Private lst_Items As List
	Private lst_Results As List
	lst_Results.Initialize


	'// Map Test
	Private lst_Mapped As List
	lst_Mapped.Initialize
	
	Private lst_OriginalValues As List
	lst_OriginalValues.Initialize
	lst_OriginalValues.AddAll( Array As Int( 6, 8, 14, 20, 202, 194 ) )
	
	Private s_Function As String
	Private n_Result As Int
	s_Function = "PlusOne"
	
	lst_Mapped = mod_Functional.List_Map( "mod_Functional", "PlusOne", lst_OriginalValues )


	'// Reduce Tests
	lst_Items.Initialize
	lst_Items.AddAll( Array As String( "one", "two", "three", "four", "five" ) )
	Private s_Items As String
	s_Items = ""
	n_Count = 0
	s_Items = mod_Functional.List_Reduce( "mod_Functional", "Concatdat", lst_Items )


	lst_Items.Initialize
	lst_Items.AddAll( Array As Int( 1, 2, 3, 4, 5 ) )
	Private n_Items As Int
	n_Items = mod_Functional.List_Reduce( "mod_Functional", "Plus", lst_Items )
		
	lst_Items.Initialize
	lst_Items.AddAll( Array As Int( 1, 7 ) )
	Private n_Items As Int
	n_Items = mod_Functional.List_Reduce( "mod_Functional", "Plus", lst_Items )
	


	'// Filter Test
	lst_Items.Initialize
	lst_Items.AddAll( Array As Int( 1, 2, 3, 4, 5 ) )
	lst_Results.Initialize
	lst_Results = mod_Functional.List_Filter( "mod_Functional", "IsEven", lst_Items )

'...
'...
'...

End sub

Sub PlusOne( n_Int As Int ) As Int
Return n_Int + 1
End Sub



'// ******************* In mod_Functional.bas *******************
Sub List_Map( s_Component As String, s_Function As String, lst As List ) As Object
	'// Contains implied assignments, because of the automatic initialization
	'// , but the variables mutate only once
	Private n_Count As Int
	Private lst_Results As List
	lst_Results.Initialize
	Return List_Map_with_InitialValues( s_Component, s_Function, lst, n_Count, lst_Results )
End Sub



Sub List_Map_with_InitialValues( s_Component As String, s_Function As String, lst As List, n_Count As Int, lst_Results As List ) As List

	If lst_Results.IsInitialized == False Then
		lst_Results.Initialize
	End If

	'// If function doesn't exist, return an empty list.
	If SubExists( s_Component, s_Function ) == False Then
		Return lst_Results
	End If

	'// If the count is up to the length of the list, then return final result
	If n_Count == lst.Size Then
		Return lst_Results
	Else
		
		Return List_Map_with_InitialValues( s_Component, s_Function, lst, n_Count + 1, AddItemToList( lst_Results, CallSub2( s_Component, s_Function, lst.Get( n_Count ) ) ) )
	End If
	
End Sub

'// There has to be an assignment, so we're isolating it here.
Sub AddItemToList( lst As List, x_Item As Object ) As List
	lst.Add( x_Item )
	Return lst
End Sub



Sub List_Reduce( s_Component As String, s_Function As String, lst As List ) As Object
	'// Contains implied assignments, because of the automatic initialization
	'// , but the variables mutate only once
	Private n_Count As Int
	Private x_Reduced As Object
	Return List_Reduce_with_InitialValues( s_Component, s_Function, lst, n_Count, x_Reduced )
End Sub


Sub List_Reduce_with_InitialValues( s_Component As String, s_Function As String, lst As List, n_Count As Int, x_Reduced As Object ) As Object

	'// If function doesn't exist, return the original object
	If SubExists( s_Component, s_Function ) == False Then
		Return x_Reduced
	End If


	'// If there's only one element in the source list, then just return its single value
	If lst.Size == 1 Then
		Return lst.Get( 0 )
	End If

	'// If there are only 2 elements in the source list, then combine those two, and return the result
	If lst.Size = 2 Then
		Return CallSub3( s_Component, s_Function, lst.Get( 0 ), lst.Get( 1 ) )
	End If
	
	If n_Count = 0 Then
		x_Reduced = lst.Get( 0 )
	End If

	If n_Count+1 == lst.Size Then
		Return x_Reduced
	Else
		Return List_Reduce_with_InitialValues( s_Component, s_Function, lst, n_Count+1, CallSub3( s_Component, s_Function, x_Reduced, lst.Get( n_Count+1 ) ) )
	End If
	
End Sub



Sub List_Filter( s_Component As String, s_Filter As String, lst As List ) As List
	'// Contains implied assignments, because of the automatic initialization
	'// , but the variables mutate only once
	Private n_Count As Int
	Private lst_Results As List
	lst_Results.Initialize
	Return List_Filter_with_InitialValues( s_Component, s_Filter, lst, n_Count, lst_Results )
	
End Sub

Sub List_Filter_with_InitialValues( s_Component As String, s_Filter As String, lst As List, n_Count As Int, lst_Results As List ) As List
	
	
	If lst_Results.IsInitialized == False Then
		lst_Results.Initialize
	End If

	'// If function doesn't exist, return an empty list.
	If SubExists( s_Component, s_Filter ) == False Then
		Return lst_Results
	End If

	'// If the count is up to the length of the list, then return final result
	If n_Count == lst.Size Then
		Return lst_Results
	Else
		'// If Filter Predicate returns true, then include the original item in the Result list
		If CallSub2( s_Component, s_Filter, lst.Get( n_Count ) ) == True Then
			Return List_Filter_with_InitialValues( s_Component, s_Filter, lst, n_Count + 1, AddItemToList( lst_Results, lst.Get( n_Count ) ) )
		Else
			Return List_Filter_with_InitialValues( s_Component, s_Filter, lst, n_Count + 1, lst_Results )
		End If
	End If
	
	
End Sub

' Callable functions for testing
Sub IsEven( n As Int ) As Boolean
	Return n Mod 2 == 0
End Sub


Sub PlusOne( n_Int As Int ) As Int
	Return n_Int + 1
End Sub

Sub Plus( n_Int1 As Int, n_Int2 As Int ) As Int
	Return n_Int1 + n_Int2
End Sub


Sub Concatdat( s1 As String, s2 As String ) As String
	Return s1 & s2
End Sub



'...
'...
'...



End Sub
 
Top