6

I have two lists a and b of the same length. And another list a2 which contains all elements from a and some others. Now I want to construct a list b2 so that for the shared elements between a2 and a, the corresponding elements in b2 and b are the same, and for those elements in a2 but not a, the values in b2 should be placeholder 0.

Example:

a = {1, 2, 5, 8};
b = {10, 20, 50, 80};
a2 = {1, 2, 4, 5, 8, 9};
(*Output b2={10,20,0,50,80,0}*)

I know how to achieve this in C-like languages, so I'm wondering if there is a better way of doing this in Mathematica. Thanks!

P.S. a and a2 are both ordered. And no duplicate exsists in either list, if it helps.

arax
  • 1,831
  • 12
  • 16

6 Answers6

5

For all versions:

Replace[a2, Append[Thread[a -> b], _ -> 0], 1]
{10, 20, 0, 50, 80, 0}

If you need speed look at Dispatch.

For versions 10.0 or later Association functionality is fast and concise:

Lookup[AssociationThread[a, b], a2, 0]
{10, 20, 0, 50, 80, 0}

Tersely Thread works in place of AssociationThread but it causes a redundant evaluation:

Lookup[Thread[a -> b], a2, 0]
{10, 20, 0, 50, 80, 0}
Mr.Wizard
  • 271,378
  • 34
  • 587
  • 1,371
3
Fold[Insert[#1, 0, #2] &, b, Position[Map[Position[a, #] &, a2], {}]]

{10, 20, 0, 50, 80, 0}

Probably faster with large lists:

Fold[Insert[#1, 0, #2] &, b, Position[a2, Alternatives @@ Complement[a2, a]]]
eldo
  • 67,911
  • 5
  • 60
  • 168
2

The most obvious :

If[MemberQ[a, #], b[[Position[a, #][[1, 1]]]], 0] & /@ a2

{10, 20, 0, 50, 80, 0}

andre314
  • 18,474
  • 1
  • 36
  • 69
2

Some pure "mathematical" ad hoc:

a2 /. Thread[a -> b] /. Thread[Complement[a2, a] -> 0]

{10, 20, 0, 50, 80, 0}

garej
  • 4,865
  • 2
  • 19
  • 42
1
mia = MapIndexed[Rule[#2, t[#1]] &, a];
mib = MapIndexed[Rule[#2, #1] &, b];
mic = MapIndexed[Rule[t[#1], #2] &, a2];
Normal@SparseArray[mib /. (mia /. mic), Length[a2]]
(*{10, 20, 0, 50, 80, 0}*)
Basheer Algohi
  • 19,917
  • 1
  • 31
  • 78
0
 b2 = Sort[Join[{#, 0} & /@ Complement[a2, a], Join[Partition[Riffle[a, b], 2]]]][[All, 2]]

{10, 20, 0, 50, 80, 0}