I have to make a program that gives as a result the union of two lists using a For loop. I can't figure out how to inspect if the elements of a list are different. Any help?

  • 1
    $\begingroup$ Have you seen the function Union? $\endgroup$ – C. E. Apr 14 '15 at 16:01

I hope I'm not late to this fun-filled party of disfunctional-programming!

unionFor[list1_, list2_] := 
 Module[{lista = {list1[[1]]}, listb = {list2[[1]]}, list, i, j},
  For[i = 1, i <= Length[list1], i++,
   For[j = 1, j <= Length[lista], j++,
     If[list1[[i]] == lista[[j]], Break[]];
     If[j >= Length[lista], AppendTo[lista, list1[[i]]]]
  For[i = 1, i <= Length[list2], i++,
   For[j = 1, j <= Length[listb], j++,
     If[list2[[i]] == listb[[j]], Break[]];
     If[j >= Length[listb], AppendTo[listb, list2[[i]]]]
  list = lista;
  For[i = 1, i <= Length[listb], i++,
   For[j = 1, j <= Length[lista], j++,
     If[listb[[i]] == lista[[j]], Break[]];
     If[j == Length[lista], AppendTo[list, listb[[i]]]];
   ]; list]

list1 = RandomInteger[10, 5]
list2 = RandomInteger[10, 5]

(*{3, 8, 4, 3, 7}*)
(*{9, 10, 5, 4, 9}*)

unionFor[list1, list2]
(*{3, 8, 4, 7, 9, 10, 5}*)

EDIT explanation of the code

There's three double-nested For loops here. The first two are identical and serve to delete the duplicates from the inputted lists. The last one takes the second list, takes its element and then cycles over the first list to see if it also has that element. If a match is found it Break[]'s the execution of the inner For loop and continues on to the next element of the second list. If no match is found, no Break happens and the counter j eventually reaches its maximum value which is equal to the length of the first list. If that (j==Lengt[lista]) happens, the element being tested for possible matches is AppendTo-ed the output list.

  • $\begingroup$ How does the last for loop work? $\endgroup$ – zermelovac Apr 14 '15 at 18:18
  • $\begingroup$ The explanation is a bit long-winded, so I've added it as an edit to my answer. $\endgroup$ – LLlAMnYP Apr 14 '15 at 20:24
  • $\begingroup$ Admittedly, this answer was put together offhand for the lulz, so even as far as iterative loops go, it's quite a bad example. For instance, it will break if given empty lists as input and there are surely several better ways to do this with For loops. One idea that comes to mind and would give the same result is Join[list1,list2] then delete the duplicates from that list using the same procedure as in my answer. $\endgroup$ – LLlAMnYP Apr 14 '15 at 20:29
  • $\begingroup$ This can be done with two sets of loops. Not sure why you needed three. Its still so ugly I'm not going to post it though $\endgroup$ – george2079 Apr 14 '15 at 20:52
  • $\begingroup$ As I said, it's doable in one loop too. Depends on the restrictions imposed by the task. I came up with three loops to be more or less symmetric wrt each of the lists - delete duplicates from one (that's one loop), from the next (that's two), add elements from one list to the other, checking for repeats - three. With a bit of thought outside the box there's always room for improvement. $\endgroup$ – LLlAMnYP Apr 14 '15 at 20:58

Instead of using a for loop, you may consider Union straight away:

Union[RandomInteger[10, 3], RandomInteger[10, 3]]
    (*{0, 4, 6, 9, 10}  Obviously result will different for each run *)

Presumably you are doing this as a programming exercise otherwise you would use Union.

To perform a manual union you might consider using a binary search to locate and Insert items in a list. However as Mathematica lists are implemented as arrays this is doomed to have poor computational complexity unless you compile it. A rudimentary example:

(* your input lists *)
a = {3, 0, 1, 4};
b = {5, 1, 2, 0};


in = Join[a, b];     (* concatenate all input lists *)
out = {First[in]};

 p = BinarySearch[out, x];
 If[! IntegerQ[p], out = Insert[out, x, ⌈p⌉] ],
 {x, in}

{0, 1, 2, 3, 4, 5}
  • $\begingroup$ Ahh, sorry I misread, I will delete :P $\endgroup$ – Jacob Akkerboom Apr 14 '15 at 17:13

Done in utterly non-functional style 80's Basic-ish:

union[lst1_, lst2_] := 
 Module[{res = {}, lists = Join[lst1, lst2], member},

  member[lst_, mem_] := (For[k = 1, k <= Length@lst, k++,
     If[lst[[k]] === mem, Return[True]]]; False);

  For[j = 1, j <= Length@lists, j++,
   If[member[res, lists[[j]]], Continue[], AppendTo[res, lists[[j]]]]];
  • 1
    $\begingroup$ Some people are so used to functional programming, that even their iterative loops look like functional programming... $\endgroup$ – LLlAMnYP Apr 14 '15 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.