2010-07-05 46 views
5

Với một mảng:Làm thế nào để tách một mảng?

arr = [['a', '1'], ['b','2'], ['c', '3']] 

Whats cách tốt nhất để chia nó thành hai mảng?

Ví dụ từ các mảng trên, chúng tôi muốn có được hai mảng sau:

first = ['a','b','c'] 
second = ['1', '2', '3'] 

tôi có thể làm điều này bằng collect?

+1

'Array.unzip' sẽ đến tiện dụng ở đây. Thật không may, không có ai .. – mykhal

Trả lời

15

ok tôi chỉ cần stumbled khi arr.transpose

arr = [['a', '1'], ['b','2'], ['c', '3']].transpose 

first = arr[0] 

second = arr[1] 

so với các câu trả lời trên arr.zip, arr.map, và foreach, mà là nhiều hơn hiệu quả? Hoặc đó là giải pháp thanh lịch nhất?

HOẶC (Nhờ bình luận bởi Jörg W Mittag - xem bình luận dưới đây) nhất, nhì = arr.transpose

+0

Transpose là giải pháp thanh lịch nhất IMHO (nhưng tôi là một nhà toán học). Tôi không chắc chắn đó là hiệu quả nhất, nhưng tôi cược rằng zip, transpose và foreach là khá nhiều như nhau, và bản đồ là hơi chậm hơn. Foreach sẽ có lợi thế nếu bạn không muốn tất cả các phần tử trong mỗi hàng (ví dụ: hai phần ba hoặc thứ gì đó). – You

+2

Điều này về cơ bản là toàn bộ điểm chuyển tiếp, vì vậy nó gần như được đảm bảo là hiệu quả nhất. Những người khác có bộ phận chuyển động hơi hơn, thường dẫn đến hiệu quả kém hiệu quả hơn. Tôi nghi ngờ sự khác biệt thường là rất lớn. Phương pháp transpose chắc chắn là dễ đọc nhất, mặc dù, do đó sẽ là cộng lớn nhất trong cuốn sách của tôi. (Tôi luôn miễn cưỡng nói một phương pháp * là hiệu quả nhất, khoảng thời gian *, bởi vì hiệu suất quirks trong các phiên bản khác nhau của Ruby thường sẽ làm cho một kẻ nói dối của tôi một ngày nào đó.) – Chuck

+11

Bạn có thể sử dụng binducturing bind: 'first, second = arr .transpose'. Thanh lịch hơn nhiều.Và kể từ khi chúng tôi đang tẩy lông trên hiệu suất ở đây: nhóm JRuby đang làm việc trên một trình biên dịch tối ưu hóa mạnh mẽ có thể loại bỏ các mảng trung gian khi sử dụng binducturing bind, multiple assignment, nhiều giá trị trả về, đối số splat và tương tự. (Trong thực tế, trình biên dịch tốt đến nỗi tác giả của nó đã yêu cầu họ viết lại một số phần Java của JRuby trong Ruby vì nó thực sự sẽ nhanh hơn.) –

1
arr = [['a', '1'], ['b','2'], ['c', '3']] 

a = [] 
b = [] 

arr.each{ |i| a << i[0]; b << i[1] } 
+0

hmm ok tôi chỉ stumbled khi arr.traspose arr = [['a', '1'], ['b', '2'], ['c', '3 ']]. transpose đầu tiên = arr [0] giây = arr [1] tôi tự hỏi cái nào hiệu quả hơn –

+1

tôi nghĩ rằng nó sẽ không quan trọng cho 3 mục :-) thử một số thử nghiệm thời gian sử dụng các mục lớn hơn và một số dữ liệu giống với dữ liệu thực của bạn –

0

Bạn có thể thực hiện việc này thông qua thu thập (bí danh bản đồ), nhưng không phải trong một thao tác đơn lẻ, vì bản đồ/thu thập luôn trả về một mảng. Bạn có thể làm

first = arr.map { |element| element[0] } 
second = arr.map { |element| element[1] } 

trong đó có những bất lợi của iterating trên arr hai lần. Tuy nhiên, điều đó thường không phải là một vấn đề, trừ khi bạn đang đối phó với một số lượng lớn các yếu tố hoặc hoạt động này phải chạy một số lượng lớn các lần.

4

Sử dụng phương pháp zip là khá thanh lịch cũng như:

arr[0].zip *arr[1..-1] 
first = arr[0] 
second = arr[1] 
+1

... điều này cũng khá giống với việc thực hiện arr.transpose. – You

Các vấn đề liên quan