2011-08-07 28 views
5

どのように私はMathematicaの変換する機能をトランスポーズ/収集/収集使用しない収集/収集の使用:Mathematicaが適切に

{ { {1, foo1}, {2, foo2}, {3, foo3} }, { {1, bar1}, {2, bar2}, {3, bar3} } } 

{ {1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3} } 

にEDIT:感謝を!私は単純な方法があることを望んでいたが、私はそう思わない!ここで

+5

UnsortedUnion @@@ #~Flatten~{2} & 

参照をより良い。あなたの例は推測するほど多くのことを残します。 –

+0

はい、具体的に質問を更新してください。現在はかなり曖昧です。 –

+0

barrycarter、私はまだ明確な質問を待っています。 –

答えて

7

はあなたのリストは以下のとおりです。ここで

tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}} 

が一つの方法です:

In[84]:= 
Flatten/@Transpose[{#[[All,1,1]],#[[All,All,2]]}]&@ 
    GatherBy[Flatten[tst,1],First] 

Out[84]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}} 

EDIT

ここでは、楽しみのためだけに、完全に異なるバージョンです:

In[106]:= 
With[{flat = Flatten[tst,1]}, 
    With[{rules = Dispatch[[email protected]@@flat]}, 
     Map[{#}~Join~ReplaceList[#,rules]&,DeleteDuplicates[flat[[All,1]]]]]] 

Out[106]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}} 
[OK]を

In[113]:= 
Module[{f},f[x_]:={x}; 
    Apply[(f[#1] = {f[#1],#2})&,tst,{2}]; 
    Flatten/@Most[DownValues[f]][[All,2]]] 

Out[113]= {{1,foo1,bar1},{2,foo2,bar2},{3,foo3,bar3}} 

EDIT 3

を、すべての考えの方のために:

EDIT 2

そして、ここではその結果を蓄積するためにリンクされたリストと内部機能を使用して、さらに別の方法であります上記の複雑すぎる、ここでは本当に簡単なルールベースのソリューションです:

In[149]:= 
GatherBy[Flatten[tst, 1], First] /. els : {{n_, _} ..} :> {n}~Join~els[[All, 2]] 

Out[149]= {{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}} 
+1

編集3では、 'els:'は何を意味するのですか?次のパターンに名前を付ける方法ですか? – DavidC

+0

@David Yep。 http://reference.wolfram.com/mathematica/ref/Pattern。html –

+4

@David:標準の 'x_'は実際に' x:_ 'の略ですが、前者は非常に一般的で、多くの人が後者を認識しません。どちらも '' Blank [] '"と一致する 'x'という名前のパターンが読み込まれます。 – Simon

3

たぶん少しovercomplicated、しかし:

Scan[Sow[#[[1]]] &, 
    Flatten[lst, 1]] // Reap // Last // Last // DeleteDuplicates 

はあなたのリスト項目のそれぞれの独特の最初の要素を返し、それらは播種したために、(DeleteDuplicates決して以降:

ここ
lst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}} 

Map[ 
    Flatten, 
    {Scan[Sow[#[[1]]] &, 
       Flatten[lst, 1]] // Reap // Last // Last // DeleteDuplicates, 
    Scan[Sow[#[[2]], #[[1]]] &, 
      Flatten[lst, 1]] // Reap // Last} // Transpose 
] 
(* 
{{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}} 
*) 

が、これがどのように動作するかです要素を並べ替える)。その後、

Scan[Sow[#[[2]], #[[1]]] &, 
     Flatten[lst, 1]] // Reap // Last 

Reap返す式は異なるリストに相違タグを播種という事実を利用します。だから一緒に置いて転置してください。

これは2回スキャンするという欠点があります。

EDIT:

この

Map[ 
    Flatten, 
    {[email protected]#[[1]], 
      Rest[#]} &@[email protected][ 
       Scan[(Sow[#[[1]]]; Sow[#[[2]], #[[1]]];) &, 
        Flatten[lst, 1]]] // Transpose 
] 

は、(非常に)わずかに速いですが、でも、読みにくくています...

8

おそらく簡単に:

tst = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}}; 

GatherBy[Flatten[tst, 1], First] /. {{k_, n_}, {k_, m_}} -> {k, n, m} 
(* 
-> {{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}} 
*) 
+0

最後の編集まで解答は見ませんでした。私は同じ行で考えていましたが、理解するまでに時間がかかった主な問題は、ルールベースのアプローチでサブリスト内の任意の数の用語を処理することでした。 –

+0

@レオニードあなたは正しいですが、そのような一般化が質問で尋ねられるかどうかわかりません –

+0

あなたは正しい、そうではないかもしれません。 –

6

MapThread

もし「foo」と「bar」の部分リストは、(彼らは一例であると)互いに整列されることが保証され、あなたの場合

data={{{1,foo1},{2,foo2},{3,foo3}},{{1,bar1},{2,bar2},{3,bar3}}}; 

MapThread[{#1[[1]], #1[[2]], #2[[2]]}&, data] 
:その後、 MapThreadで十分で、 Gather/ Collect/ Transpose以外の機能を使用して検討します

結果:

{{1, foo1, bar1}, {2, foo2, bar2}, {3, foo3, bar3}} 

リストはないが、あなたはまた、ストレートパターンマッチングと置換を使用することができ整列している場合

パターンマッチング(私は大規模なリストのために、このアプローチをお勧めしませんが) :

data //. 
    {{h1___, {x_, foo__}, t1___}, {h2___, {x_, bar_}, t2___}} :> 
    {{h1, {x, foo, bar}, t1}, {h2, t2}} // First 

ソウ/シェムリアップ

整列されていないリストのためのより効率的なアプローチはSowReapを使用しています:

Reap[Cases[data, {x_, y_} :> Sow[y, x], {2}], _, Prepend[#2, #1] &][[2]] 
+0

私は同じアイデアを持っていましたが、あなたの純粋な機能の代わりにユニオンを使っていました... –

4

またちょうど楽しみのために...

DeleteDuplicates /@ Flatten /@ GatherBy[Flatten[list, 1], First] 

どこ

list = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, 
    bar3}}} 

編集。

ここではいくつかのより多くの楽しみ...

Gather[#][[All, 1]] & /@ Flatten /@ GatherBy[#, First] & @ 
Flatten[list, 1] 
+0

これはかなり正確に私が書いたコードです... – Simon

+0

@Simonはい、それはそれを行う最も直接的な方法です。しかし、そこでの楽しみはどこですか? :) – acl

+0

@サイモン。私はあなたのコードを見ませんでした。私はWReachが答えを投稿したのと同じようにこれを投稿しました。私はそれを削除することを考えましたが、そこに残すことを決めました... – tomd

5

は、私はこの方法は非常に汎用的であるWhat is in your Mathematica tool bag?

l = {{{1, foo1}, {2, foo2}, {3, foo3}}, {{1, bar1}, {2, bar2}, {3, bar3}}}; 

SelectEquivalents[ 
    l 
    , 
    MapLevel->2 
    , 
    TagElement->(#[[1]]&) 
    , 
    TransformElement->(#[[2]]&) 
    , 
    TransformResults->(Join[{#1},#2]&) 
] 

に掲載SelectEquivalentsのバージョンを使用して、それを行うだろうかです。私はモンテカルロシミュレーションで生成した巨大なリストを扱うためにGatherByのような関数を使用していました。 SelectEquivalentsでは、このような操作の実装がはるかに直感的です。それはMathematicaで非常に高速なReapとSowの組み合わせに基づいています。

3

質問は、より明確かつ具体的に更新されるまでの間、私は私が何をしたいと仮定しますと、この提案:機能要件は多少書かれている可能性が私見UnsortedUnion

+1

ようこそmr.wizard。良い休暇はありましたか?あなたはこの質問(http://stackoverflow.com/q/6505675/615464)を見ましたか?私はあなたがそれを好きになると思う;-) –

+0

@ Sjoerdありがとう、そしてはい。いいえ、私はしていませんでした。笑! –