web-dev-qa-db-ja.com

多次元の結果にならないようにするにはどうすればよいでしょうか。

somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

somearray.Push(anotherarray.flatten!)

期待していた

["some","thing","another","thing"]
424
ncvncvn

実用的なアイディアを持っていますが、#flatten!は間違った場所にあります - それは受信機を平らにするので、[1, 2, ['foo', 'bar']][1,2,'foo','bar']に変えるためにそれを使うことができます。

私は間違いなくいくつかのアプローチを忘れていますが、あなたは 連結することができます

a1.concat a2
a1 + a2              # creates a new array, as does a1 += a2

または プレフィックス/追加

a1.Push(*a2)         # note the asterisk
a2.unshift(*a1)      # note the asterisk, and that a2 is the receiver

または スプライス

a1[a1.length, 0] = a2
a1[a1.length..0] = a2
a1.insert(a1.length, *a2)

または 追加して平坦化

(a1 << a2).flatten!  # a call to #flatten instead would return a new array
658
pilcrow

+演算子を使用するだけです。

irb(main):001:0> a = [1,2]
=> [1, 2]
irb(main):002:0> b = [3,4]
=> [3, 4]
irb(main):003:0> a + b
=> [1, 2, 3, 4]

あなたはここで配列クラスについてのすべてを読むことができます: http://Ruby-doc.org/core/classes/Array.html

195
micmoo

最も明確な方法は、 Array#concat メソッドを使用することです。これは新しい配列を作成しません(同じことを行いますが新しい配列を作成するArray#+とは異なり)。

ドキュメントから直接( http://www.Ruby-doc.org/core-1.9.3/Array.html#method-i-concat ):

連結(other_ary)

Other_aryの要素を自分自身に追加します。

そう

[1,2].concat([3,4])  #=> [1,2,3,4]  

Array#concat は、多次元配列が引数として渡された場合、それを平坦化しません。あなたはそれを別に扱う必要があるでしょう:

arr= [3,[4,5]]
arr= arr.flatten   #=> [3,4,5]
[1,2].concat(arr)  #=> [1,2,3,4,5]

最後に、Rubyコアクラスに便利なヘルパーを追加する私達のcorelib gem( https://github.com/corlewsolutions/corelib )を使うことができます。特に、連結を実行する前に多次元配列を自動的に平坦化する Array#add_all メソッドがあります。

62

Rubyのバージョン> = 2.0では動作するが古いバージョンでは動作しない簡単な方法:

irb(main):001:0> a=[1,2]
=> [1, 2]
irb(main):003:0> b=[3,4]
=> [3, 4]
irb(main):002:0> c=[5,6]
=> [5, 6]
irb(main):004:0> [*a,*b,*c]
=> [1, 2, 3, 4, 5, 6]
33
Ludovic Kuty

これを試してください、それはあなたの配列を組み合わせて重複を取り除きます

array1 = ["foo", "bar"]
array2 = ["foo1", "bar1"]

array3 = array1|array2

http://www.Ruby-doc.org/core/classes/Array.html

さらなる文書は "Set Union"を見てください。

32
g00se0ne

ここでは2つの方法があります。この場合、最初の方法で新しい配列が割り当てられることに注意してください(somearray = somearray + anotherarrayに変換されます)。

somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

somearray += anotherarray # => ["some", "thing", "another", "thing"]

somearray = ["some", "thing"]
somearray.concat anotherarray # => ["some", "thing", "another", "thing"]
27
Joshua Cheek

(array1 + array2).uniq

これにより、最初にarray1要素を取得します。重複することはありません。

19
slindsey3000

問題は、本質的に、「Rubyで配列を連結する方法」です。当然のことながら、ほとんどすべての回答で述べられているように、答えはconcatまたは+を使用することです。

この質問に対する自然な拡張は、「Rubyで2次元配列を行ごとに連結する方法」です。私が "Rubyの連結行列"とグーグルしたとき、このSOの質問が一番の結果でしたので、私はここで私の答えを子孫のためにここに残します.


アプリケーションによっては、2つの2D配列を行方向に "連結"したい場合があります。何かのようなもの、

[[a, b], | [[x],    [[a, b, x],
 [c, d]] |  [y]] =>  [c, d, y]]

これは行列を「増強する」ようなものです。たとえば、このテクニックを使用して、多数の小さい行列からグラフを表す単一の隣接行列を作成しました。このテクニックがなければ、エラーが発生しやすくなるか、考えるのが面倒になる可能性がある方法でコンポーネントを反復処理する必要がありました。例えば、私はeach_with_indexをしなければならなかったかもしれません。代わりに、 Zipflatten を次のように組み合わせました。

# given two multi-dimensional arrays that you want to concatenate row-wise
m1 = [[:a, :b], [:c, :d]]
m2 = [[:x], [:y]]

m1m2 = m1.Zip(m2).map(&:flatten)
# => [[:a, :b, :x], [:c, :d, :y]]
8
Ziggy

それをするためのもう一つの方法です。

[somearray, anotherarray].flatten
=> ["some", "thing", "another", "thing"]
8
Datt

@ Pilcrowの答えを詳しく説明すると、巨大な配列に適した唯一の答えはconcat+)です。これは高速で、ループ内で操作するときにガベージコレクションの対象となる新しいオブジェクトを割り当てないためです。

これがベンチマークです。

require 'benchmark'

huge_ary_1 = Array.new(1_000_000) { Rand(5_000_000..30_000_00) }

huge_ary_2 = Array.new(1_000_000) { Rand(35_000_000..55_000_00) }

Benchmark.bm do |bm|
  p '-------------------CONCAT ----------------'
  bm.report { huge_ary_1.concat(huge_ary_2) }

  p '------------------- Push ----------------'
  bm.report { huge_ary_1.Push(*huge_ary_2)  }
end

結果:

       user     system      total        real
"-------------------CONCAT ----------------"
  0.000000   0.000000   0.000000 (  0.009388)
"------------------- Push ----------------"
  example/array_concat_vs_Push.rb:13:in `block (2 levels) in <main>': stack level too deep (SystemStackError)

ご覧のとおり、Pushを使用すると、配列が十分に大きい場合に _ error _ stack level too deep (SystemStackError)がスローされます。

7
juliangonzalez
a = ["some", "thing"]
b = ["another", "thing"]

baに追加し、その結果をaに格納するには、次のようにします。

a.Push(*b)

または

a += b

どちらの場合もaは次のようになります。

["some", "thing", "another", "thing"]

しかし前者の場合、bの要素は既存のa配列に追加され、後者の場合、2つの配列は連結され、結果はaに格納されます。

7
snibbets

["some", "thing"] + ["another" + "thing"]

5
samg

新しいデータが配列またはスカラであり、新しいデータが配列の場合にネストされないようにするには、スプラット演算子が最適です。スカラーの場合はスカラー、配列の場合はパックされていない引数のリストを返します。

1.9.3-p551 :020 > a = [1, 2]
 => [1, 2] 
1.9.3-p551 :021 > b = [3, 4]
 => [3, 4] 
1.9.3-p551 :022 > c = 5
 => 5 
1.9.3-p551 :023 > a.object_id
 => 6617020 
1.9.3-p551 :024 > a.Push *b
 => [1, 2, 3, 4] 
1.9.3-p551 :025 > a.object_id
 => 6617020 
1.9.3-p551 :026 > a.Push *c
 => [1, 2, 3, 4, 5] 
1.9.3-p551 :027 > a.object_id
 => 6617020 
4
a = ['a', 'b']
b = ['c', 'd']
arr = [a, b].flatten

これで重複は削除されませんが、

a|b

重複を削除します。

3
AustintheCleric

私は誰もreduceを言及していませんが、これはあなたが配列の配列を持っているときうまくいきます:

lists = [["a", "b"], ["c", "d"]]
flatlist = lists.reduce(:+)  # ["a", "b", "c", "d"]
3
ScottJ

次のように、配列をプッシュまたは追加してから定位置に平坦化する方が簡単です。

somearray = ["some", "thing"]
anotherarray = ["another", "thing"]
somearray.Push anotherarray # => ["some", "thing", ["another", "thing"]]
#or
somearray << anotherarray # => ["some", "thing", ["another", "thing"]]
somearray.flatten!  # => ["some", "thing", "another", "thing"]
somearray # => ["some", "thing", "another", "thing"]
2
nas