I have two list operations which I would like to ask for help. The way I implemented them is not very elegant, so I want to learn from you experts.
1) Suppose I have two lists, one is like {{0,2,4},{1,3,2},{2,0,4}}
and the other is {{1,3,7},{2,4,6},{3,1,9}}
. I want to either based on the value, or based on some criterion to filter through the first list, and then get the corresponding elements in the second. For example, based on value which is non-zero, I want to get {{3,7},{2,4,6},{3,9}}
. Based on the condition greater than 2, I want to get {{7},{4},{9}}
.
2) I have a list such as {{{1,2},{1,1}},{{1,3},{2,4}},{{1,2},{2,3}},{{1,4},{3,3}}}
. I want to form {{{1,2},{{1,1},{2,3}}},{{1,3},{{2,4}}},{{1,4},{{3,3}}}
. That is, I want to group those second lists if the first element is the same. How can I do this in a beautiful way?
Many thanks.
For the first part, you want Pick
:
In[27]:= Pick[{{1,3,7},{2,4,6},{3,1,9}},{{0,2,4},{1,3,2},{2,0,4}},_?Positive]
Out[27]= {{3,7},{2,4,6},{3,9}}
In[28]:= Pick[{{1,3,7},{2,4,6},{3,1,9}},{{0,2,4},{1,3,2},{2,0,4}},_?(#>2&)]
Out[28]= {{7},{4},{9}}
For the second question, GatherBy
gets you most of the way there:
In[29]:= x = GatherBy[{{{1, 2}, {1, 1}}, {{1, 3}, {2, 4}}, {{1, 2},
{2, 3}}, {{1, 4}, {3, 3}}}, First]
Out[29]= {{{{1, 2}, {1, 1}}, {{1, 2}, {2, 3}}}, {{{1, 3},
{2, 4}}}, {{{1, 4}, {3, 3}}}}
And then you can apply a rule to clean things up a bit:
In[30]:= x /. l:{{a_, _}..} :> {a, Last /@ l}
Out[30]= {{{1, 2}, {{1, 1}, {2, 3}}}, {{1, 3}, {{2, 4}}},
{{1, 4}, {{3, 3}}}}
As Michael said, Pick
is definitely the way to go for the first one.
For the second part, I'd like to offer an alternative that lets you do this in one line: SelectEquivalents
. (I know, rather self promoting, but I use this function a lot.) To get the result your looking for, simply enter
In[1] := SelectEquivalents[ <list>, First, Last, {#1,#2}& ]
Out[1]:= {{{1, 2}, {{1, 1}, {2, 3}}}, {{1, 3}, {{2, 4}}}, {{1, 4}, {{3, 3}}}}
Internally, SelectEquivalents
uses Reap
and Sow
, so First
tags each element in <list>
, Last
transforms the element into the form we wish to use, and {#1, #2}&
returns a list with elements of the form {Tag, {<items with that tag>}}
. The advantage is that you get to specify everything in one step getting you what you want without subsequent transformations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With