আপনি রুবিতে অন্য অ্যারে কীভাবে অ্যারে যুক্ত করবেন এবং বহুমাত্রিক ফলাফল দিয়ে শেষ করবেন না?


474
somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

somearray.push(anotherarray.flatten!)

আমি আশা করেছিলাম

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

6
এটি বলার অপেক্ষা রাখে না (আপনাকে দুঃখ না দেওয়ার জন্য, তবে এটি আপনাকে বারবার কামড় দেবে) কারণ আপনার প্রত্যাশা এখানে সমস্যা। রুবি অ্যারেগুলি (পার্লের অ্যারে বলার মত নয়) এই জাতীয় প্রসঙ্গে স্বয়ংক্রিয়ভাবে সমতল হয় না । এটি কোনও বাগ নয়: এটি একটি বৈশিষ্ট্য।
টেলিমাচাস

3
ri Array@flatten!কেন এই প্রশ্ন এত ভোট পাচ্ছে? ডকটি স্পষ্টভাবে Array#flatten! ফ্ল্যাটটেনস স্ব স্থানে রয়েছে। কোনও পরিবর্তন না করা হলে শূন্য করে (যেমন, অ্যারেতে কোনও
সাবারি নেই

7
প্রশ্নগুলি যদি ব্যবহারকারীদের জন্য দরকারী হয় তবে তা উত্সাহ পেতে পারে। সহজ প্রশ্নগুলি সর্বাধিক উন্নত হয় কারণ এগুলি বেশিরভাগ লোকের পক্ষে কার্যকর।
Ziggy

@ ইয়ো, আপনি কি ভাবেন না যে চ্যাপ্টা অপারেশন বিনামূল্যে?
কনস্টান্টিন

@ কনস্টান্টিন অপ বিকল্পের সন্ধান করছেন না বা পারফরম্যান্স সম্পর্কিত সমস্যা নিয়ে কথা বলছেন না, অপ এমন ফলাফলের প্রত্যাশা করছিল যা সে বা সে পায়নি কারণ flatten!সেভাবে কাজ করে না। অবশেষে, প্রশ্নটি একটি অপ্টিমাইজেশান সমস্যার চেয়ে লজিক সমস্যা প্রতিফলিত করে। আরও জানতে নীচে পাইলক্রোর উত্তর দেখুন।
ইয়েও

উত্তর:


713

আপনি একটি কার্যক্ষম ধারণা পেয়েছেন, তবে এটি #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

17
একমাত্র (5 টির মধ্যে আমি দেখতে পাচ্ছি) হয়ে থাকার জন্য ভাল কাজ করেছেন যারা উপস্থাপিত কোডটিতে আসলে কী ভুল ছিল তা নির্দেশ করেছিলেন। +1
মাইক উডহাউস

53
কনকটের পরিবর্তে পুশ ব্যবহার করা তৃতীয় অ্যারে তৈরি এড়ানো হয়, তাই এটি বৃহত অ্যারেগুলির জন্য পছন্দনীয়।
ফাতেমন

8
আমি নক্ষত্রের সাথে ধাক্কা ভালবাসি। খুব মার্জিত.

14
@phatmann সংযুক্তকরণ সঙ্গে Array#concatএকটি নতুন অ্যারে বরাদ্দ নয়, সংযুক্তকরণ সঙ্গে Array#+করে
cbliard

5
এই উত্তরটি কেবলমাত্র অনুপস্থিত তা হ'ল প্রতিটি পদ্ধতির তুলনামূলক মানদণ্ড। +1 টি!
টেরা অ্যাশলে

205

আপনি শুধু +অপারেটর ব্যবহার করতে পারেন !

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


15
পোস্টারটি জানতে চেয়েছিল যে কীভাবে বিদ্যমান অ্যারেতে সংশ্লেষ করা যায়, কোনও নতুন অ্যারে তৈরি করা হয়নি যা দুটি অ্যারের মিল ছিল।
ফাতেমন

1
দ্রষ্টব্য: a+= bএকটি নতুন অ্যারে তৈরি করেছে:c = a = [1,2] ; b = [3,4] ; a += b ; puts c #=> [1,2]
কেব্রোক 14

1
@ কেব্রোক সঠিক যদি বড় অ্যারে নিয়ে কাজ করে থাকেন তবে আপনি push@ পিলক্রো দ্বারা বর্ণিত পদ্ধতিটি দেখতে চাইবেন।
জোশুয়া পিন্টার

2
মনে রাখবেন যে +=নতুন বস্তু তৈরি করে। যেমন উদাহরণে [1, 2].each_with_object([]) { |number, object| object+=number }খালি অ্যারে []ফিরিয়ে দেওয়া হবে
ফিলিপ বার্টুজি

1
আইটেম যোগ করা একটি অ্যারের থাকতে হবে
RousseauAlexandre

66

সবচেয়ে পরিষ্কার পন্থাটি অ্যারে # কনট্যাট পদ্ধতিটি ব্যবহার করা ; এটি কোনও নতুন অ্যারে তৈরি করবে না (অ্যারে # + এর বিপরীতে যা একই কাজ করবে তবে একটি নতুন অ্যারে তৈরি করবে)।

সরাসরি দস্তাবেজগুলি থেকে ( http://www.ruby-doc.org/core-1.9.3/Array.html#method-i-concat ):

CONCAT (other_ary)

অন্যান্য_আর উপাদানগুলিকে স্বতে যুক্ত করে।

সুতরাং

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

অ্যারে # কনক্যাট যদি একটি আর্গুমেন্ট হিসাবে পাস করা হয় তবে এটি একটি বহুমাত্রিক অ্যারে সমতল করবে না। আপনার এটি আলাদাভাবে পরিচালনা করতে হবে:

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

শেষ অবধি, আপনি আমাদের কোরলিব রত্ন ব্যবহার করতে পারেন ( https://github.com/corlewsolutions/corelib ) যা রুবি কোর শ্রেণিতে দরকারী সহায়ক যুক্ত করে। বিশেষত আমাদের একটি অ্যারে # অ্যাড_ল পদ্ধতি রয়েছে যা কনক্যাট চালানোর আগে স্বয়ংক্রিয়ভাবে বহুমাত্রিক অ্যারে সমতল করে দেবে।


1
আপনি সাধারণত অপরিবর্তনশীলতা চান, সুতরাং একটি নতুন অ্যারে তৈরি করা ভাল ধারণা।
ভাসিলাকিসফিল

5
"আপনি সাধারণত অপরিবর্তনশীলতা চান" সঠিক নয়। পূর্ণ সময়ের সফ্টওয়্যার বিকাশের 20+ বছরে আমি প্রতিদিনের ভিত্তিতে সব ধরণের অ্যারে এবং সংগ্রহের সাথে কাজ করেছি। কখনও কখনও আপনি জায়গায় বিদ্যমান অ্যারে পরিবর্তন করে। কখনও কখনও আপনার একটি নতুন উদাহরণ দিয়ে কাজ করা প্রয়োজন।
কলিউ সলিউশন

35

সহজ পদ্ধতি যা রুবি সংস্করণ> = 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]

2
@ আইকুটি এটি এখন পর্যন্ত সবচেয়ে মার্জিত সমাধান আমি খুঁজে পেয়েছি, আপনি *এখানে কী ঘটছে তা দয়া করে ব্যাখ্যা করতে পারেন ?
অভিনেত

@ আবিনে প্ল্যাট অপারেটর অ্যারের উপাদানগুলিতে বিস্ফোরিত হয় এভাবে শেষ লাইনে একটি একক মাত্রা অ্যারে তৈরি করে।
ওমর আলী

[*a, *b]রুবির পুরানো সংস্করণে ব্যর্থ হয়, অর্থাত্, 1.8.7। এবং রুবি যতটা আপনার জীবনের বাইরে বলতে চায়, আরএইচইএল 6 এখনও রক্ষণাবেক্ষণ করা হয়, যা রুবি 1.8 কে একটি উল্লেখযোগ্য টার্গেট সংস্করণ করে তোলে।
ওথিয়াস

1
আমি মনে করি না যে এই উত্তরটি -1 ন্যায্যতা প্রমাণ করে। ওপি দ্বারা বর্ণিত কোনও রুবি সংস্করণ নয়, রুবি সংস্করণটি উত্তরে স্পষ্টভাবে উল্লিখিত হয়েছে, তাই ... আপনি পূর্ববর্তী আলফা 0.0.0.0.1 সংস্করণের সাথে পিছনে সামঞ্জস্য থাকতে চান? এটি রুবি সংস্করণের উপর নির্ভর করে ভাল সমাধানগুলির মধ্যে একটি
লুডোভিচ কিউটি

1
কেবলমাত্র উল্লেখ করতে যে এই উত্তরটি খুব মুখ্য প্রতিচ্ছবিযুক্ত জাভাস্ক্রিপ্ট ES6 এর সাথে খুব 'অনুরূপ' যেখানে আপনি করতে পারতেন [...array1, ...array2], কেবল মনে রাখবেন যে splatরুবিতে অপারেটরের *পরিবর্তে হবে ...। এটি মনে রাখা সহজ করে তোলে
Sandre89 89

34

এটি ব্যবহার করে দেখুন, এটি আপনার অ্যারেগুলিকে সদৃশগুলি সরিয়ে একত্রিত করবে

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

array3 = array1|array2

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

"সেট ইউনিয়ন" এ আরও ডকুমেন্টেশন দেখুন


এটি একটি বা, এটি কোনও সদৃশ উপাদান ছাড়াই একটি অ্যারে প্রদান করে, এখানে তিনি সম্ভবত যা জিজ্ঞাসা করছেন তা কীভাবে করবেন না তার একটি উদাহরণ রয়েছে, প্রথম অ্যারেতে দুটি "বাজ" এক হয়ে যায় এবং "বার" দ্বিতীয় অ্যারে যোগ করা হয় না। অ্যারে 1 = ["foo", "বার", "বাজ", "বাজ"] অ্যারে 2 = ["foo1", "বার 1", "বার"] অ্যারে 3 = অ্যারে 1 | অ্যারে 2 অ্যারে 3 # => ["ফু", "বার "," বাজ "," foo1 "," বার 1 "]
জোশুয়া গাল

বা আরও ভাল:array1 |= [ "foo1", "bar1" ] #=> [ "foo", "bar", "foo1", "bar1" ]
জোশুয়া পিন্টার

33

এখানে দুটি উপায় রয়েছে, এক্ষেত্রে লক্ষ্য করুন যে প্রথম উপায়ে একটি নতুন অ্যারে নির্ধারিত হয়েছে (সুমেরে = স্যারারি + অ্যানোথারারে অনুবাদ করে)

somearray = ["some", "thing"]

anotherarray = ["another", "thing"]

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

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

24
a = ["some", "thing"]
b = ["another", "thing"]

সংযোজন করতে bকরতে aএবং ফলাফলের সংরক্ষণ a:

a.push(*b)

অথবা

a += b

উভয় ক্ষেত্রেই হয় a:

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

তবে পূর্ববর্তী ক্ষেত্রে, উপাদানগুলি bবিদ্যমান aঅ্যারেতে যুক্ত হয় এবং পরবর্তী ক্ষেত্রে দুটি অ্যারে একসাথে মিশে যায় এবং ফলাফলটি সংরক্ষণ করা হয় a


2
নোট যে a.push(*b)হিসাবে ঠিক একই নয় a += b। প্রাক্তন বিদ্যমান অ্যারেতে নতুন উপাদান যুক্ত করে; পরেরটি সমস্ত উপাদানগুলির সাথে একটি নতুন অ্যারে তৈরি করে এবং এটি নির্ধারিত করে a। পার্থক্যটি দেখতে পাচ্ছেন যদি আপনি কোনও পদ্ধতি সংযোজন aa = aকরার aআগে রেফটি সংরক্ষণ করতে চান এবং তারপরে পরীক্ষা করেন aa। পূর্ববর্তী ক্ষেত্রে এটির নতুন মানটির সাথে পরিবর্তন হয় aএবং পরবর্তীকালে এটি অপরিবর্তিত থাকে।
ডেভ হার্টনল

20

(array1 + array2).uniq

এইভাবে আপনি প্রথমে অ্যারে 1 উপাদান পান। আপনি কোনও সদৃশ পাবেন না


9

@ পিলক্রোর উত্তরটি বিশদভাবে বর্ণনা করা বিশাল অ্যারেগুলির একমাত্র উপযুক্ত উত্তর 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কোনও ত্রুটি ব্যবহার করছে : stack level too deep (SystemStackError)যখন অ্যারেগুলি যথেষ্ট পরিমাণে বড় হয়।


8

প্রশ্নটি মূলত, "রুবিতে অ্যারেগুলি কীভাবে সংযুক্ত করতে হয়" is স্বাভাবিকভাবেই উত্তরটি ব্যবহার করা concatবা +প্রায় প্রতিটি উত্তরে উল্লিখিত হয়।

এই প্রশ্নের একটি প্রাকৃতিক বর্ধন হ'ল "রুবীতে 2D অ্যারেগুলির সারি-ভিত্তিক উপসংহার কীভাবে করা যায়"। আমি যখন "রুবি কনটেনেটেট ম্যাট্রিকেস" গগল করেছি, তখন এই এসও প্রশ্নটি শীর্ষ ফলাফল ছিল তাই আমি ভেবেছিলাম যে উত্তর (উত্তরবিহীন তবে সম্পর্কিত) প্রশ্নের উত্তর আমি উত্তরবংশের জন্য এখানে রেখে দেব।


কিছু অ্যাপ্লিকেশনে আপনি "2 টি ডি অ্যারেগুলি সারিবদ্ধভাবে" যুক্ত করতে চান। কিছুটা এইরকম,

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

এটি একটি ম্যাট্রিক্সকে "বৃদ্ধি" করার মতো কিছু like উদাহরণস্বরূপ, আমি এই কৌশলটি ছোট ম্যাট্রিক্সের একগুচ্ছের বাইরে একটি গ্রাফ উপস্থাপন করার জন্য একটি একক সংলগ্ন ম্যাট্রিক্স তৈরি করতে ব্যবহার করেছি। এই কৌশলটি ছাড়াই আমার এমন উপাদানগুলির পুনরাবৃত্তি করতে হবে যা সম্পর্কে ভ্রান্ত প্রবণ বা হতাশ হতে পারে। each_with_indexউদাহরণস্বরূপ আমার একটি কাজ করতে হবে । পরিবর্তে আমি জিপ এবং নিম্নরূপে সমতল করা,

# 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

এটি করার আরও একটি উপায়।

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

flattenযথাসম্ভব যতদূর সম্ভব সবকিছুকে চটজলদি করুন rec এমনকি নেস্টেড অ্যারে। ফলস্বরূপ, যদি somearrayবা anotherarrayনেস্টেড অ্যারে থাকে তবে সেগুলিও সমতল হয়। এটি এমন পার্শ্ব-প্রতিক্রিয়া যা সাধারণত উদ্দেশ্যে করা হয় না।
হেজেলো

5

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


আমি দক্ষতা সম্পর্কে জানি না, তবে এটি রুবি 1.8 এর জন্য কাজ করে। সাধারণভাবে, [*a] + [*b]কাজ করে
ওথিয়াস

আমি মনে করি না যে "another" + "thing"এটি প্রত্যাশার মতো কাজ করবে।
অ্যালেক্সিস উইলক

5

নতুন ডেটা যদি অ্যারে বা স্কেলার হতে পারে এবং আপনি যদি নতুন ডেটাটি অ্যারে হ'ল বাসা বাঁধতে চান তবে স্প্ল্যাট অপারেটর দুর্দান্ত! এটি একটি স্কেলারের জন্য একটি স্কেলার এবং একটি অ্যারের জন্য যুক্তিগুলির একটি প্যাকযুক্ত তালিকা দেয় returns

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

আমি অবাক হলাম কেউই উল্লেখ করেনি reduce, যখন আপনার অ্যারেগুলির একটি অ্যারে থাকে তখন এটি ভাল কাজ করে:

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

4
a = ['a', 'b']
b = ['c', 'd']
arr = [a, b].flatten

এটি ডুপস সরবে না, তবে but

a|b

ডুপস সরিয়ে দেয়


দ্রষ্টব্য: এটি পুনরাবৃত্তভাবে সমস্ত অভ্যন্তরীণ অ্যারেগুলিকেও সমান করে তোলে।
মিরোদিনহো

2

অ্যারেগুলিকে চাপতে বা সংযোজন করা আমার পক্ষে আরও সহজ মনে হয় এবং তারপরে সেগুলি স্থলে সমতল করা যায়:

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"]

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.