Cách đúng đắn để:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
hoặc để có được số lượng các mục trong đó?
Cách đúng đắn để:
is_array("something") # => false (or 1)
is_array(["something", "else"]) # => true (or > 1)
hoặc để có được số lượng các mục trong đó?
Câu trả lời:
Bạn có thể muốn sử dụng kind_of()
.
>> s = "something"
=> "something"
>> s.kind_of?(Array)
=> false
>> s = ["something", "else"]
=> ["something", "else"]
>> s.kind_of?(Array)
=> true
kind_of?()
hơn các giải pháp khác? Một số giải thích về lợi ích của câu trả lời của bạn so với những người khác sẽ hữu ích cho độc giả trong tương lai.
Bạn có chắc chắn nó cần phải là một mảng? Bạn có thể có thể sử dụng respond_to?(method)
để mã của bạn sẽ hoạt động cho những thứ tương tự không nhất thiết là mảng (có thể là một số thứ đáng ghen tị khác). Nếu bạn thực sự cần một array
, thì bài viết mô tả Array#kind\_of?
phương pháp là tốt nhất.
['hello'].respond_to?('each')
respond_to?(:to_ary)
.
Thay vì kiểm tra Array,
chỉ chuyển đổi bất cứ thứ gì bạn có được thành một cấp Array,
để mã của bạn chỉ cần xử lý một trường hợp.
t = [*something] # or...
t = Array(something) # or...
def f *x
...
end
Ruby có nhiều cách khác nhau để hài hòa một API có thể lấy một đối tượng hoặc một mảng các đối tượng, vì vậy, hãy đoán xem tại sao bạn muốn biết nếu một cái gì đó là một Array, tôi có một gợi ý.
Các splat điều hành chứa rất nhiều ma thuật bạn có thể nhìn lên, hoặc bạn chỉ có thể gọi Array(something)
đó sẽ thêm một wrapper Mảng nếu cần thiết. Nó tương tự như [*something]
trong trường hợp này.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1 # => "[1]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
Hoặc, bạn có thể sử dụng splat trong khai báo tham số và sau đó .flatten
, cung cấp cho bạn một loại trình thu thập khác. (Đối với vấn đề đó, bạn cũng có thể gọi .flatten
ở trên.)
def f *x
p x.flatten.inspect
end # => nil
f 1 # => "[1]"
f 1,2 # => "[1, 2]"
f [1] # => "[1]"
f [1,2] # => "[1, 2]"
f [1,2],3,4 # => "[1, 2, 3, 4]"
Và, cảm ơn gregschlom , đôi khi chỉ cần sử dụng nhanh hơn Array(x)
bởi vì khi nó đã Array
không cần thiết phải tạo một đối tượng mới.
[*nil] => []
. Vì vậy, bạn có thể kết thúc với một mảng trống.
Array(foo)
hiệu quả hơn nhiều so với[*foo]
[1,2,3].is_a? Array
đánh giá là đúng.
is_a?
trong toàn bộ chủ đề này. Gần nhất là a [1,2,3].is_a? Enumerable
. Tôi vẫn nghĩ rằng nó có giá trị trong khi có câu trả lời này.
Có vẻ như bạn đang theo đuổi thứ gì đó có khái niệm về vật phẩm. Vì vậy, tôi khuyên bạn nên xem nếu nó là Enumerable
. Điều đó cũng đảm bảo sự tồn tại của #count
.
Ví dụ,
[1,2,3].is_a? Enumerable
[1,2,3].count
lưu ý rằng, trong khi size
, length
và count
tất cả các công việc cho mảng, count
là ý nghĩa đúng ở đây - (ví dụ, 'abc'.length
và 'abc'.size
cả hai đều hoạt động, nhưng 'abc'.count
không hoạt động như vậy).
Chú ý: một chuỗi is_a? Vô số, vì vậy có lẽ đây không phải là điều bạn muốn ... phụ thuộc vào khái niệm của bạn về một mảng giống như đối tượng.
Thử:
def is_array(a)
a.class == Array
end
EDIT : Câu trả lời khác tốt hơn nhiều so với của tôi.
Cũng xem xét sử dụng Array()
. Từ Hướng dẫn Phong cách Cộng đồng Ruby :
Sử dụng Mảng () thay vì kiểm tra Mảng rõ ràng hoặc [* var], khi xử lý một biến bạn muốn coi là Mảng, nhưng bạn không chắc chắn đó là một mảng.
# bad
paths = [paths] unless paths.is_a? Array
paths.each { |path| do_something(path) }
# bad (always creates a new Array instance)
[*paths].each { |path| do_something(path) }
# good (and a bit more readable)
Array(paths).each { |path| do_something(path) }
to_a
được gọi trên mỗi đối số được thêm vào mảng mới, vì vậy Array({id: 100})
trả về[[:id, 100]]