2
$\begingroup$

I have a Table which includes {Numbers, Probabilities}.

For example A= {{1,0.5},{2,0.25}, {3,0.1},{4,0.9}……{100,0.1}}. Put attention that the numbers are 1,2….100 in order.

I have a List of random numbers (same length like the Table and can include duplicates).

For example B={2,5,100,500, 61,250,8……19}.

I would like to build an short algorithm that will :

(1) Choose each number in List B and check if its appear in Table A,

(2) If it's there, for example "2" it will be a term in a new Table C which includes again {Number, Probability from Table A) = {2,0.25} . Here we build a new Table C.

(3) If the number in List B does not appears in A than Null (nothing).

I will be thankful to get a solution.

$\endgroup$
3
  • $\begingroup$ So lists A and B have 100 elements, but list C will have a length some number less than 100? $\endgroup$
    – Jason B.
    Commented Apr 29, 2016 at 7:47
  • $\begingroup$ Yes, That's the idea. $\endgroup$
    – Danny
    Commented Apr 29, 2016 at 7:55
  • 1
    $\begingroup$ You should clarify what you mean by Null - do you mean nothing, no element there, in which list C will be smaller than lists A and lists B, or do you specifically want to have the word Null in those positions? From your answer above I assume you want the first, but others have interpreted your question as it was written $\endgroup$
    – Jason B.
    Commented Apr 29, 2016 at 12:53

6 Answers 6

3
$\begingroup$

For a shorter example, lets take A and B to have 20 elements instead of 100, and have the integers in B run from 0 to 40,

nElements = 20;
maxB = 40;
listA = Table[{n, RandomReal[]}, {n, nElements}]
listB = RandomInteger[maxB, nElements]
(* {{1, 0.350025}, {2, 0.651077}, {3, 0.444575}, {4, 
  0.261574}, {5, 0.40258}, {6, 0.670888}, {7, 0.388662}, {8, 
  0.675527}, {9, 0.496563}, {10, 0.356305}, {11, 0.58421}, {12, 
  0.93864}, {13, 0.984511}, {14, 0.871462}, {15, 0.581234}, {16, 
  0.643948}, {17, 0.373181}, {18, 0.821704}, {19, 0.950593}, {20, 
  0.921725}} *)
(* {11, 24, 28, 35, 6, 28, 39, 23, 33, 8, 3, 27, 33, 18, 18, 
24, 16, 19, 5, 19} *)

This will give you the list you are after:

listA[[Pick[listB, 1 <= # <= nElements & /@ listB]]]
(* {{3, 0.0380246}, {11, 0.311671}, {14, 0.842235}, {8, 
  0.381485}, {6, 0.43467}, {14, 0.842235}, {16, 0.560073}, {11, 
  0.311671}, {8, 0.381485}, {3, 0.0380246}} *)
$\endgroup$
1
  • $\begingroup$ Thx a lot JasonB. $\endgroup$
    – Danny
    Commented Apr 29, 2016 at 8:06
2
$\begingroup$
f = With[{l1 = #, l2 = #2}, If[MemberQ[l1[[All, 1]], #], l1[[#]]] & /@ l2] &;

SeedRandom[3]
n = 10;
probs = Differences@Join[{0}, Sort@RandomVariate[UniformDistribution[], n - 1], {1}];
listA = Transpose[{Range[n], probs}]

{{1, 0.00869692}, {2, 0.130583}, {3, 0.0413228}, {4, 0.166427}, {5, 0.0572686}, {6, 0.074256}, {7, 0.0501474}, {8, 0.0498856}, {9, 0.181763}, {10, 0.239651}}

listB = RandomInteger[{1, 2 n}, 10]

{14, 10, 1, 9, 9, 20, 15, 6, 3, 12}

listC = f[listA, listB];
listC

{Null, {10, 0.239651}, {1, 0.00869692}, {9, 0.181763}, {9, 0.181763}, Null, Null, {6, 0.074256}, {3, 0.0413228}, Null}

$\endgroup$
2
$\begingroup$

Interpreting the question as kglr has done, and using listA and listB as given in kglr's answer:

Cases[listA, {#, x_} :> Sequence[#, x]] & /@ listB /. {} -> Null

{Null, {10, 0.239651}, {1, 0.00869692}, {9, 0.181763},

{9, 0.181763}, Null, Null, {6, 0.074256}, {3, 0.0413228}, Null}

Or

Cases[listA, {#, x_} :> Sequence[#, x]] & /@ listB /. {} -> Nothing

{{10, 0.239651}, {1, 0.00869692}, {9, 0.181763}, {9, 0.181763},

{6, 0.074256}, {3, 0.0413228}}

$\endgroup$
2
$\begingroup$
SeedRandom[0];

n = 10;

la = Transpose[{Range[n], RandomReal[1, n]}]

{{1, 0.652468}, {2, 0.63307}, {3, 0.682813}, {4, 0.566352},
{5, 0.935202}, {6, 0.976188}, {7, 0.238452}, {8, 0.637562},
{9, 0.101098}, {10, 0.645525}}

lb = RandomInteger[{1, 2 n}, 10]

{6, 4, 12, 8, 6, 10, 7, 17, 11, 18}

Using Lookup

Lookup[Cases[la, {a_, b_} :> a -> {a, b}], lb, Null]

{{6, 0.976188}, {4, 0.566352}, Null, {8, 0.637562},
{6, 0.976188}, {10, 0.645525}, {7, 0.238452}, Null, Null, Null}

Without Null:

Lookup[Cases[la, {a_, b_} :> a -> {a, b}], lb, Nothing]

{{6, 0.976188}, {4, 0.566352}, {8, 0.637562},
{6, 0.976188}, {10, 0.645525}, {7, 0.238452}}

$\endgroup$
1
$\begingroup$

For a solution that follows your algorithm to the letter, you would need something like this:

Map[ If[ MemberQ[ A[[;; , 1]] , #],  AppendTo[c, A[[#]]]] &, B]

I used c instead of C because C is a protected symbol.

$\endgroup$
1
$\begingroup$

Grabbing the @eldo's example:

SeedRandom[0];

n = 10;

la = Transpose[{Range[n], RandomReal[1, n]}];

lb = RandomInteger[{1, 2 n}, 10];

Using Reap and Sow:

newTable[la_List, lb_List] := Module[{nset, res},
nset = AssociationThread[la[[All, 1]], la[[All, 2]]];
Reap[Do[If[KeyExistsQ[nset, b], Sow[{b, nset[b]}], Sow[Null]], {b, lb}]][[2, 1]]];

Lookup[Cases[la, {a_, b_} :> a -> {a, b}], lb, Null] === newTable[la, lb]

True

$\endgroup$

Your Answer

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

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