B4J Code Snippet List_Map function - any suggestions?

Hi,

Does anyone have suggestions about improving upon the following code, to make it more robust and universal? Even suggestions about adding some explanatory comments, or better naming conventions, would be fine.

The purpose is to create a Function that executes a given function on every element in a List, and returns a List with the results. Something like PHP’s array_map(), or Clojure’s map() function.


B4X:
Sub List_Map( s_Component As String, s_Function As String, lst As List, n_Count As Int, lst_Reduced As List ) As List


	Private x_Result As Object
	
	If lst_Reduced.IsInitialized == False Then
		lst_Reduced.Initialize
	End If

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

		'// Shouldn't be necessary
		'// lst_Reduced.Clear

		Return lst_Reduced
	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_Reduced
	Else
		
		'// Is there any way to avoid Adding to the list?  It's a forum of assignment, and
		'//  I'm trying to avoid assignments.
		lst_Reduced.Add( CallSub2( s_Component, s_Function, lst.Get( n_Count ) ) )
		Return List_Map( s_Component, s_Function, lst, n_Count + 1, lst_Reduced )
	End If
	
End Sub
 

B4JExplorer

Active Member
Licensed User
Longtime User
Hi,

Does anyone have suggestions about improving upon the following code, to make it more robust and universal? Even suggestions about adding some explanatory comments, or better naming conventions, would be fine.

The purpose is to create a Function that executes a given function on every element in a List, and returns a List with the results. Something like PHP’s array_map(), or Clojure’s map() function.


B4X:
Sub List_Map( s_Component As String, s_Function As String, lst As List, n_Count As Int, lst_Reduced As List ) As List


	Private x_Result As Object
	
	If lst_Reduced.IsInitialized == False Then
		lst_Reduced.Initialize
	End If

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

		'// Shouldn't be necessary
		'// lst_Reduced.Clear

		Return lst_Reduced
	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_Reduced
	Else
		
		'// Is there any way to avoid Adding to the list?  It's a forum of assignment, and
		'//  I'm trying to avoid assignments.
		lst_Reduced.Add( CallSub2( s_Component, s_Function, lst.Get( n_Count ) ) )
		Return List_Map( s_Component, s_Function, lst, n_Count + 1, lst_Reduced )
	End If
	
End Sub
The 'lst_Reduced' List should be 'lst_Results'. I cloned and modified this function from one called 'List_Reduce()', and neglected to rename this parameter.
 

XbNnX_507

Active Member
Licensed User
Longtime User
B4X:
Sub AppStart (Form1 As Form, Args() As String)

    Dim o() As Object  = array_map( "multiply", Array As Object(1, 2, 3, 4, 5) )
    For i = 0 To o.Length-1
        Log( o(i) )
    Next

   o = array_map("cube", array as object(1, 2,3,4,5)
  For i = 0 To o.Length-1
        Log( o(i) )
    Next

End Sub

Sub array_map( CallBack As String, Args() As Object ) As Object()
    If SubExists( Me , CallBack) = False Then Return Args
    Dim obj(Args.Length) As Object
    For v= 0 To Args.Length-1
        obj(v) =  CallSub2(Me, CallBack, Args(v))
    Next
    Return obj
End Sub

Sub multiply( value As Object ) As Int
    Return value * 2
End Sub

Sub cube( value As Object ) As Int 
    Return value * value * value
End Sub
 
Last edited:

B4JExplorer

Active Member
Licensed User
Longtime User
B4X:
Sub AppStart (Form1 As Form, Args() As String)

    Dim o() As Object  = array_map( "multiply", Array As Object(1, 2, 3, 4, 5) )
    For i = 0 To o.Length-1
        Log( o(i) )
    Next

   o = array_map("cube", array as object(1, 2,3,4,5)
  For i = 0 To o.Length-1
        Log( o(i) )
    Next

End Sub

Sub array_map( CallBack As String, Args() As Object ) As Object()
    If SubExists( Me , CallBack) = False Then Return Args
    Dim obj(Args.Length) As Object
    For v= 0 To Args.Length-1
        obj(v) =  CallSub2(Me, CallBack, Args(v))
    Next
    Return obj
End Sub

Sub multiply( value As Object ) As Int
    Return value * 2
End Sub

Sub cube( value As Object ) As Int 
    Return value * value * value
End Sub
Yep, that's more general, but I'll still have to take out the assignments and convert the loop to a recursion.

Anyway, looks pretty good, I'll play with it during the week, thanks Xb.
 
Top