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.
4 Answers
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}} *)
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.
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}
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}}
A
andB
have 100 elements, but listC
will have a length some number less than 100? $\endgroup$Null
- do you mean nothing, no element there, in which listC
will be smaller than listsA
and listsB
, or do you specifically want to have the wordNull
in those positions? From your answer above I assume you want the first, but others have interpreted your question as it was written $\endgroup$