Apakah Anda ingin array yang sebenarnya, atau hanya sesuatu yang mirip array?
Kathy Van Stone
1
Tidak ada keamanan jenis di Ruby. Jangan khawatir tentang variabel Anda menjadi array atau tidak. Metode ini harus mengasumsikan bahwa itu adalah, dan teruskan dan panggil hitung di atasnya: my_array.count
user132447
Silakan baca jawaban oleh zgchurch dan DigitalRoss untuk mengetahui Ruby yang lebih idiomatis.
Pengecekan tipe untuk Java. Silakan dan panggil saja jumlah variabel. Tulis pengujian unit untuk memastikan metode ini berfungsi seperti yang diharapkan.
user132447
14
@ user132447 sebenarnya java adalah tipe aman sehingga Anda tidak perlu khawatir tentang memeriksa semua jenis
grinch
8
Saya menurunkan ini sekarang karena saya pikir ini bukan praktik yang baik dalam bahasa seperti Ruby. Jawaban oleh @zgchurch jelas merupakan pendekatan yang jauh lebih idiomatis terhadap pertanyaan itu. Dalam kasus-kasus seperti ini, saya pikir jauh lebih masuk akal untuk mencoba dan mencari tahu apa arti OP, daripada secara membabi buta memberinya senapan ...
Per Lundberg
1
Mengapa Anda ingin menggunakan kind_of?()solusi lain? Beberapa penjelasan tentang manfaat jawaban Anda terhadap orang lain akan membantu pembaca di masa mendatang.
AlbertEngelB
148
Apakah Anda yakin itu perlu array? Anda mungkin dapat menggunakan respond_to?(method)sehingga kode Anda akan bekerja untuk hal-hal serupa yang belum tentu array (mungkin beberapa hal yang dapat diatasi). Jika Anda benar-benar membutuhkan array, maka postingan yang menjelaskan Array#kind\_of?metode yang terbaik.
Dalam hal ini saya yakin itu akan menjadi Array. Tapi senang mengetahui metode ini juga. +1
BuddyJoe
Ide menarik, saya menggunakan push / pop pada struktur data. Apakah selain array akan merespon metode tersebut?
Drew
3
Jika Anda menginginkan sesuatu yang lebih mirip array, Anda mungkin menginginkannya respond_to?(:to_ary).
Andrew Grimm
21
Secara umum, ini adalah praktik yang baik untuk pengembangan OO. Saya membaca di mana seseorang pada dasarnya berkata: jangan membayangkan bahwa Anda memanggil metode pada objek Anda. Anda mengirimi mereka pesan. Jika suatu objek tahu bagaimana menanggapi pesan Anda, Anda tidak peduli kelas apa itu, atau apakah ada metode yang menamainya, atau apakah secara dinamis membuat respons melalui metode_missing. Yang penting adalah, bisakah itu menanggapi pesan Anda? Ini memungkinkan abstraksi fungsi dan implementasi yang lebih baik. Anda dapat mengubah objek apa yang Anda gunakan nanti, selama masih merespons dengan benar.
Nathan Long
2
Satu-satunya masalah dengan ini adalah mengatakan saya ingin memeriksa apakah ada sesuatu yang dapat diindeks, jadi array, daftar tertaut, dll. Akan keren, tapi saya tidak ingin menyimpan nilai kunci seperti hash?
Colton Voege
58
Alih-alih menguji Array,hanya mengkonversi apa pun yang Anda dapatkan menjadi satu tingkat Array,sehingga kode Anda hanya perlu menangani satu kasus.
t =[*something]# or...
t =Array(something)# or...def f *x
...end
Ruby memiliki berbagai cara untuk menyelaraskan API yang dapat mengambil objek atau Array objek, jadi, tebak mengapa Anda ingin tahu apakah ada sesuatu yang terjadi. Array, saya punya saran.
The percikan Operator berisi banyak sihir Anda dapat melihat, atau Anda hanya dapat memanggil Array(something)yang akan menambahkan wrapper Array jika diperlukan. Mirip dengan [*something]kasus yang satu ini.
def f x
p Array(x).inspect
p [*x].inspect
end
f 1# => "[1]"
f [1]# => "[1]"
f [1,2]# => "[1, 2]"
Atau, Anda bisa menggunakan percikan dalam deklarasi parameter dan kemudian .flatten, memberi Anda jenis kolektor yang berbeda. (Dalam hal ini, Anda bisa menelepon ke .flattenatas juga.)
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]"
Dan, terima kasih gregschlom , kadang-kadang lebih cepat hanya digunakan Array(x)karena ketika sudah menjadi Arraytidak perlu membuat objek baru.
Apa yang ini tambahkan ke jawaban yang telah ada di situs selama hampir tujuh tahun ..?
Martin Tournoij
6
@Carpetsmoker tidak ada jawaban ringkas yang merujuk is_a?pada keseluruhan utas ini. Yang terdekat adalah a [1,2,3].is_a? Enumerable. Saya masih berpikir ada baiknya sementara memiliki jawaban ini.
dipole_moment
4
Anda tahu .. Anda sebenarnya benar ... Saya berani bersumpah saya melihat itu di sana sebelumnya: - / Selamat!
Martin Tournoij
16
Sepertinya Anda mencari sesuatu yang memiliki beberapa konsep barang. Dengan demikian saya akan merekomendasikan melihat apakah itu Enumerable. Itu juga menjamin keberadaan #count.
Sebagai contoh,
[1,2,3].is_a?Enumerable[1,2,3].count
perhatikan bahwa, sementara size, lengthdan countsemua berfungsi untuk array, countadalah makna yang tepat di sini - (misalnya, 'abc'.lengthdan 'abc'.sizekeduanya berfungsi, tetapi 'abc'.counttidak berfungsi seperti itu).
Perhatian: string is_a? Dapat dihitung, jadi mungkin ini bukan yang Anda inginkan ... tergantung pada konsep Anda tentang objek seperti array.
Gunakan Array () alih-alih centang Array eksplisit atau [* var], saat berurusan dengan variabel yang ingin Anda perlakukan sebagai Array, tetapi Anda tidak yakin itu adalah array.
# 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)}
Ini akan menghasilkan hasil yang tidak terduga ketika melewati Hash karena to_adipanggil pada setiap argumen yang ditambahkan ke array baru, jadi Array({id: 100})kembali[[:id, 100]]
Jawaban:
Anda mungkin ingin menggunakannya
kind_of()
.sumber
is_a?
daninstance_of?
. Lihat stackoverflow.com/questions/3893278/…kind_of?()
solusi lain? Beberapa penjelasan tentang manfaat jawaban Anda terhadap orang lain akan membantu pembaca di masa mendatang.Apakah Anda yakin itu perlu array? Anda mungkin dapat menggunakan
respond_to?(method)
sehingga kode Anda akan bekerja untuk hal-hal serupa yang belum tentu array (mungkin beberapa hal yang dapat diatasi). Jika Anda benar-benar membutuhkanarray
, maka postingan yang menjelaskanArray#kind\_of?
metode yang terbaik.sumber
respond_to?(:to_ary)
.Alih-alih menguji
Array,
hanya mengkonversi apa pun yang Anda dapatkan menjadi satu tingkatArray,
sehingga kode Anda hanya perlu menangani satu kasus.Ruby memiliki berbagai cara untuk menyelaraskan API yang dapat mengambil objek atau Array objek, jadi, tebak mengapa Anda ingin tahu apakah ada sesuatu yang terjadi. Array, saya punya saran.
The percikan Operator berisi banyak sihir Anda dapat melihat, atau Anda hanya dapat memanggil
Array(something)
yang akan menambahkan wrapper Array jika diperlukan. Mirip dengan[*something]
kasus yang satu ini.Atau, Anda bisa menggunakan percikan dalam deklarasi parameter dan kemudian
.flatten
, memberi Anda jenis kolektor yang berbeda. (Dalam hal ini, Anda bisa menelepon ke.flatten
atas juga.)Dan, terima kasih gregschlom , kadang-kadang lebih cepat hanya digunakan
Array(x)
karena ketika sudah menjadiArray
tidak perlu membuat objek baru.sumber
[*nil] => []
. Jadi, Anda mungkin berakhir dengan array kosong.Array(foo)
jauh lebih efisien daripada[*foo]
[1,2,3].is_a? Array
mengevaluasi ke true.sumber
is_a?
pada keseluruhan utas ini. Yang terdekat adalah a[1,2,3].is_a? Enumerable
. Saya masih berpikir ada baiknya sementara memiliki jawaban ini.Sepertinya Anda mencari sesuatu yang memiliki beberapa konsep barang. Dengan demikian saya akan merekomendasikan melihat apakah itu
Enumerable
. Itu juga menjamin keberadaan#count
.Sebagai contoh,
perhatikan bahwa, sementara
size
,length
dancount
semua berfungsi untuk array,count
adalah makna yang tepat di sini - (misalnya,'abc'.length
dan'abc'.size
keduanya berfungsi, tetapi'abc'.count
tidak berfungsi seperti itu).Perhatian: string is_a? Dapat dihitung, jadi mungkin ini bukan yang Anda inginkan ... tergantung pada konsep Anda tentang objek seperti array.
sumber
Mencoba:
EDIT : Jawaban lainnya jauh lebih baik dari pada saya.
sumber
Juga pertimbangkan untuk menggunakan
Array()
. Dari Panduan Gaya Komunitas Ruby :sumber
to_a
dipanggil pada setiap argumen yang ditambahkan ke array baru, jadiArray({id: 100})
kembali[[:id, 100]]