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 at 5:37
  • $\begingroup$ thank you @Roman. Didn't think of using Position until i saw your answer. $\endgroup$ – kglr Feb 28 at 5:40
  • $\begingroup$ Ah, I see. Thank you so much! This is really helpful. $\endgroup$ – MetallicSilence Feb 28 at 8:39
  • 1
    $\begingroup$ On my machine the Position[True]@Outer[Equal, array1 - 1, array2] method performs best. $\endgroup$ – JEM_Mosig Feb 28 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

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