2012-03-03 32 views
6

Tôi mới bắt đầu học ruby. Bây giờ tôi cần phải tìm ra kích thước của một mảng đa chiều. Tôi đã xem xét ruby-docs cho tất cả các phương thức mảng, nhưng tôi không thể tìm thấy phương thức trả về thứ nguyên.lấy kích thước của mảng đa chiều trong ruby ​​

Dưới đây là một ví dụ:

Đối [[1, 2],[3,4],[5,6]] kích thước nên 2.

Đối [[[1,2],[2,3]],[[3,4],[5]]], kích thước nên 3.

Trả lời

2

Không có hàm tích hợp cho điều đó vì có thể có nhiều định nghĩa về ý nghĩa của "thứ nguyên" cho một mảng. Các mảng của Ruby có thể chứa bất cứ thứ gì kể cả băm hoặc các mảng khác. Đó là lý do tại sao tôi tin rằng bạn cần phải thực hiện chức năng của riêng bạn cho điều đó.

asuming rằng bằng cách chiều bạn có nghĩa là "mức độ lồng sâu nhất của mảng" này nên làm như lừa:

def get_dimension a 
    return 0 if a.class != Array 
    result = 1 
    a.each do |sub_a| 
    if sub_a.class == Array 
     dim = get_dimension(sub_a) 
     result = dim + 1 if dim + 1 > result 
    end 
    end 
    return result 
end 

EDIT: và như ruby ​​là một ngôn ngữ tuyệt vời và cho phép bạn thực hiện một số công cụ ưa thích bạn có thể cũng làm cho get_dimension một phương pháp Array:

class Array 
    def get_dimension 
    ... # code from above slightly modified 
    end 
end 
+0

nếu sub_a.class == Array – Short

1

trong trường hợp đơn giản nhất

depth = Proc.new do |array| 
    depth = 1 
    while Array === array.first do 
    array = array.first 
    depth += 1 
    end 
    depth 
end 

array = [[[1,2],[2,3]],[[3,4],[5]]]  
depth.call(array) 
#=> 3 

Hoặc phương pháp đệ quy nhỏ bé này

def depth(array, depth=1) 
    array = array.send(:first) 
    Array === array ? depth(array, depth+1) : depth 
end 

array = [[[1,2],[2,3]],[[3,4],[5]]]  
depth(array) 
#=> 3 
+0

Tại sao proc, không thường xuyên chức năng? –

+0

Tôi không chắc chắn, doc%) Đó là công cụ điều khiển hành vi. Tôi đã ở trong giao diện điều khiển và tôi thường sử dụng procs trong giao diện điều khiển. Tất nhiên nó có thể được viết lại như một phương pháp thông thường – fl00r

+0

Tôi chỉ tò mò, đó là tất cả :) –

0

làm thế nào về:

class Object 
    def dimension 
     self.class == Array ? 1 + self[0].dimension : 0 
    end 
end 
[[[1,2],[2,3]],[[3,4],[5]]].dimension 
#=> 3 
+1

một lần nữa sẽ không hoạt động trong trường hợp a = [3, [1,2]]. Đầu ra sẽ là 1 thay vì 2. Một sửa đổi nhỏ sẽ làm cho nó làm việc cho trường hợp đó, mặc dù. –

+0

@izomorphius - Dường như với tôi rằng 1 là giá trị đúng trong trường hợp đó. Bạn nói đúng là câu hỏi không rõ ràng. – pguardiario

6

S imple, giải pháp hướng đối tượng.

class Array 
    def depth 
    map {|element| element.depth + 1 }.max 
    end 
end 

class Object 
    def depth 
    0 
    end 
end 
0

Là một sửa đổi của phương pháp Tass của:

class Array 
    def depth 
     map{ |element| element.is_a?(Vector) ? element.depth + 1 : 1 }.max 
    end 
end 

Giữ depth như một phương pháp Array, và không đòi hỏi thêm một phương pháp để Object.

Tất nhiên, đó có thể là những gì bạn muốn nếu bạn đang đi để gọi my_object.depth, nơi mà bạn không biết trước rằng my_object.class == Array

0

tôi đã không hài lòng với các giải pháp khác vì vậy tôi đã viết một one-liner Tôi thực sự sử dụng:

def depth(array) 
    array.to_a == array.flatten(1) ? 1 : depth(array.flatten(1)) + 1 
end 

Nó sẽ làm phẳng mảng 1 vào lúc đó cho đến khi không thể làm phẳng nữa, trong khi đếm kích thước.

Tại sao điều này lại tốt hơn?

  • không yêu cầu sửa đổi đến các lớp học có nguồn gốc (tránh điều đó nếu có thể)
  • không sử dụng lập trình meta (is_a?, send, respond_to? vv)
  • khá dễ dàng để đọc
  • làm việc với băm cũng (chú ý array.to_a)
  • thực sự hoạt động (không giống như chỉ kiểm tra các chi nhánh đầu tiên, và các công cụ ngớ ngẩn khác)
Các vấn đề liên quan