4
$\begingroup$

I have two arrays, say

array1 = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
array2 = {13, 4, 6, 20, 21};

I want to compare these two arrays by cycling array1 through all elements in array2. The output should be the position in each array where they match a condition, where the condition array2[[m]] = array1[[n]]-1 is true. That is, the output should be:

output = {6,2}

Because in array2, $5-1 = 4$. (array1[[6]] = 5 and array2[[2]] = 4). So far, my code is

output = {Position[array1, #][[1, 1]], 
 Position[array2, #][[1, 1]]} & /@ (I have no idea)

Where the code on the left hand side of Map gives me the positions of a true condition. On the right hand side of Map, I'm not sure what to do.

To clarify a little bit, the code I want is similar to

output = {Position[array1, #][[1, 1]], 
Position[array2, #][[1, 1]]} & /@ Intersection[array1, array2]

Except I want the position of the element when array2 = array1-1 instead of when array1 = array2.

$\endgroup$
5
$\begingroup$

You can use Tuples to construct all pairs of positions and use Select to pick the pairs that satisfy your condition:

pairs = Tuples[{ Range[Length[array1]], Range[Length[array2]]}];
Select[pairs, array1[[#[[1]]]] - 1 == array2[[#[[2]]]] &]

{{6, 2}, {8, 3}}

You can also use Outer as follows:

Join @@ Outer[If[array1[[#]] - 1 == array2[[#2]], {##}, Nothing] &, 
  Range[Length[array1]], Range[Length[array2]]]

{{6, 2}, {8, 3}}

Yet other ways: variations on Roman's method using Position and Outer combination:

Position[1] @ Outer[Subtract, array1, array2] 
Position[True] @ Outer[Equal, array1 - 1, array2] 
Position[{i_, i_}]@Outer[List, array1 - 1, array2]

{{6, 2}, {8, 3}}

$\endgroup$
  • $\begingroup$ I like your Outer[Subtract, ... way! $\endgroup$ – Roman Feb 28 '19 at 5:37
  • $\begingroup$ thank you @Roman. Didn't think of using Position until i saw your answer. $\endgroup$ – kglr Feb 28 '19 at 5:40
  • $\begingroup$ Ah, I see. Thank you so much! This is really helpful. $\endgroup$ – user60437 Feb 28 '19 at 8:39
  • 1
    $\begingroup$ On my machine the Position[True]@Outer[Equal, array1 - 1, array2] method performs best. $\endgroup$ – JEM_Mosig Feb 28 '19 at 22:20
4
$\begingroup$

This is a general solution for any condition between the elements of array1 and array2:

Position[Outer[List, array1, array2], {i_, j_} /; j == i - 1]

{{6, 2}, {8, 3}}

@kglr's solutions are simpler than this when the condition is a difference as in the given problem.

$\endgroup$

Your Answer

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