2
$\begingroup$

I want to create a function that takes inputs that are multiple lists of ordered quadruples. For example, when we run the code our input line should read something like inputs[{2,3,4,5},{6,7,8,9},...} and return something like {14},{30},... Do I have to use a table for this or is there a way to do this when we define our function? I'm new to this and don't know how I should approach this.

$\endgroup$
2
  • $\begingroup$ f[x___] := Total /@ {x};f[{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}] $\endgroup$
    – cvgmt
    Oct 2, 2020 at 1:47
  • 3
    $\begingroup$ f[x___] := List /@ Total /@ {x}; f[{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}] $\endgroup$
    – cvgmt
    Oct 2, 2020 at 1:56

4 Answers 4

2
$\begingroup$

If you want the braces for the output as you say, then you could do something like this with a pure function:

someInput = RandomInteger[{1, 10}, {10, 4}]
{Total[#]} & /@ someInput

(* {{5, 9, 9, 9}, {2, 7, 3, 4}, {8, 4, 4, 8}, {5, 10, 8, 
  5}, {2, 7, 2, 2}, {6, 6, 5, 2}, {3, 8, 9, 6}, {8, 6, 5, 2}, {2, 10, 
  10, 1}, {2, 9, 3, 2}}

 {{32}, {16}, {24}, {28}, {13}, {19}, {26}, {21}, {23}, {16}} *)

I will note that Total doesn't care that the input list was ordered as you originally said. I encourage you to look at pure functions - they are used often and once you get used to them, you'll use them all the time.

$\endgroup$
1
$\begingroup$

You can use Table or Map functions.

ClearAll[fun] ;
fun[list_List:{a_,b_,c_,d_}] := Total[list]  ;
args = {{a1,b1,c1,d1},{a2,b2,c2,d2}} ;
Map[fun,args]
Table[fun[arg],{arg,args}]
$\endgroup$
1
$\begingroup$

It's best not to rely on input having a particular form, so ideally we would solve this in a way that added the elements of a list of lists regardless of whether they were of the same length as in the OP.

A way to do this looks at the //FullForm of the list of lists, which is something like List[List[1,2,3],List[2,3,4,5],...] and replaces the internal List heads with Plus. This will work regardless of how long each sublist is.

Plus @@ myList[[#]] & /@ Range[Length[myList]]

We need the [[#]]& Pure Function because otherwise Plus will add the first element of each list, then the second, etc. Plus@@myList therefore fails with an error if the sublists are of equal length, or gives the wrong answer if they are of equal length.

Alternatively

Provided your numeric input lists are all of equal length (not necessarily quads), this will work:

quadList = RandomInteger[{1, 5}, {8, 4}]
Total[Transpose[quadList]]

(* {{5, 3, 2, 2}, {5, 3, 4, 4}, {4, 2, 3, 2}, 
{1, 4, 5, 3}, {1, 5, 1, 5}, {1, 2, 1, 1}, {4, 2, 2, 3}, {5, 2, 2, 5}}

{12, 16, 11, 13, 12, 5, 11, 14} *)

This will also work, where we use the Blank[] to tell the ReplaceAll what it is replacing, but it depends on the lists being of equal length and will crash otherwise.

{{5,3,2,2},{5,3,4,4}}/.x_->Total[Transpose[x]]

To define a function that tests whether the input lists are of equal length we could use this, but the approach is clumsy compared with the Plus@@ solution that doesn't require equal-length lists, and answers already given by others also represent good alternatives:

sumList1[x_] := If[SameQ[Sequence @@ (Length[#] & /@ x)], Total[Transpose[x]], Print["Lists must be of equal length"]]
$\endgroup$
0
$\begingroup$

If the input is a list of lists, you can use the two-argument form of Total (i.e.Total[input, {2}]) to get the row sums, and Map (/@) List on the output:

ClearAll[f1a]
f1a[x : {{__} ..}] := List /@ Total[x, {2}]

f1a[{{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}}]
{{14}, {30}, {a + b}, {c}}

Alternatively, you can Apply (@@@) Plus at level 1 and map List on the output:

ClearAll[f2a]
f2a[x : {{__} ..}] := List /@ (Plus @@@ x)

f2a[{{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}}]
{{14}, {30}, {a + b}, {c}}

If the input is a sequence of lists, we need wrap the input sequence with List:

ClearAll[f1b]
f1b[x : {__} ..] := List /@ Total[{x}, {2}]
f1b[{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}]
{{14}, {30}, {a + b}, {c}}
ClearAll[f2b]
f2b[x : {__} ..] := List /@ (Plus @@@ {x})

f2b[{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}]
{{14}, {30}, {a + b}, {c}}

And for fun, Halloween-special versions of the above:

ClearAll[☺]
☺ = +## & @@@ {#} & /@ # &;

☺[{{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}}]
{{14}, {30}, {a + b}, {c}}
ClearAll[☺☺]
☺☺ = +## & @@@ {#} & /@ {##} &;

☺☺[{2, 3, 4, 5}, {6, 7, 8, 9}, {a, b}, {c}]
{{14}, {30}, {a + b}, {c}}
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.