Hapus cara untuk melewati elemen pertama dalam indeks berbasis loop

9

Saya memiliki loop untuk di mana saya harus melewatkan elemen pertama dalam array berbasis nol.

Manakah dari ini yang menunjukkan niat saya lebih jelas?

for($i=1 ; $i < count(array) ; $i++){
    array[$i];
}

atau

for($i=0+1 ; $i < count(array) ; $i++){
    array[$i];
}
Tomas Zubiri
sumber
28
Tidak juga, $i=2-1cara superior. : /
yannis
7
Saya mungkin akan memilih opsi pertama dan menambahkan komentar untuk menjelaskan mengapa elemen pertama harus dilewati.
Vincent Savard
3
Kejelasan adalah tujuan saya, saya mengedit pertanyaan. Apakah itu lebih jelas?
Tomas Zubiri
10
Tidak menggunakan PHP adalah cara terbaik.
kucing
3
Apakah PHP memiliki konstruksi foreach? Anda bisa melakukannya foreach ($i in range(1, count))(apa pun yang tampak seperti di PHP). Atau sesuatu seperti foreach ($item in array.skip(1))apa yang akan dilakukan orang C #.
usr

Jawaban:

23

Saya benci keduanya.

Siapa bilang Anda bisa menggunakan angka ajaib? Jika Anda akan mulai dengan offset 1, bagaimana dengan memberi tahu kami MENGAPA Anda mulai dengan offset 1. Menambahkan nol ajaib yang sama tidak menjelaskan apa-apa kepada saya.

Apakah ini payload offset? Apakah ini beberapa string pascal yang Anda konversi menjadi string c yang dihentikan nol? Tolong beri tahu kami apa yang sedang terjadi.

Maaf, tapi aku telah menyia-nyiakan karierku untuk memecahkan misteri-misteri tak berguna seperti ini dan kesabaranku untuk mereka telah menipis. Apakah variabel dengan nama yang layak benar-benar banyak bertanya?

Dengan nama yang layak maksud saya nama yang menjelaskan MENGAPA kita melewatkan elemen pertama. Bukan sesuatu yang hanya mengatakan bahwa kita melewatkan elemen pertama. Saya memberi tahu saya sendiri.

candied_orange
sumber
19
0 dan 1 bukan angka ajaib.
user949300
19
@ user949300 Oh mereka pasti ada di sini. Mereka hanyalah angka-angka yang kadang-kadang tidak ajaib. Hanya karena 2 selalu angka ajaib, tidak berarti 1 tidak pernah angka ajaib. Keajaiban datang dari makna yang hilang. Apa sih artinya dimulai dengan offset 1 di sini? Apa gunanya menambahkan 0 di sini? Oh ya angka-angka ini tentu ajaib di sini. Saya bisa melihat debu peri menetes dari mereka.
candied_orange
4
Tentu, saya akan mulai mendefinisikan static final int LONELIEST_NUMBER = 1semua kode Java saya. :-) Itu mengatakan, kalau dipikir-pikir, saya ingin undownvote jawaban Anda tetapi tidak bisa kecuali Anda mengeditnya. Konyol aturan SO?
user949300
6
@ Eiko: Jika tidak ada penjelasan mengapa loop dimulai pada elemen kedua, hampir dijamin bahwa beberapa programmer pemeliharaan akan mengubah loop untuk memulai pada elemen pertama. Itulah sebabnya angka 1 adalah angka ajaib dalam konteks ini.
Bart van Ingen Schenau
2
@ BartvanIngenSchenau Saya berasumsi akan ada alasan langsung terlihat dalam konteksnya. Seperti membandingkan elemen dengan pendahulunya (yang saya pikir sebagai kasus penggunaan yang paling sering dimulai pada 1 - dan saya gagal melihat nama konstan yang berguna di sini). Jika elemen pertama memiliki makna yang sangat khusus, desain mungkin rusak, dan harus ada perbaikan yang lebih baik daripada memberi nama indeks itu. Saya tidak mengatakan tidak pernah ada alasan untuk memperkenalkan variabel di sini. Hanya saja saya pikir kasus-kasus itu (atau mungkin hanya seharusnya) sangat jarang.
Eiko
12

Jawaban singkat: opsi pertama lebih baik.

Opsi kedua hanya menambahkan noise. Sangat tidak mungkin 0 + 1 membantu pembaca untuk memahami bahwa itu mungkin 0 tetapi 1. Kemungkinan besar dia akan bingung sesaat dan teralihkan dari apa yang dimaksud dengan loop. Terutama dalam bahasa di mana semua array mulai dari 0.

Seperti yang disebutkan lainnya, jika Anda ingin menekankan fakta bahwa loop dimulai dari 1, bukan 0, tambahkan saja komentar.

Florian F
sumber
10

Jangan bilang kami melewatkan item pertama - kami bisa melihatnya. Apa yang tidak jelas adalah alasannya . Jadi .. jika tidak jelas dari konteks, beri tahu kami alasannya:

// array[0] is just a header
for($i=1 ; $i < count(array) ; $i++){
    array[$i];
}

Atau, jika Anda menolak komentar, sesuatu seperti:

$lastHeaderIndex = 0;
for($i = $lastHeaderIndex + 1 ; $i < count(array) ; $i++){
    array[$i];
}

Jangan gunakan komentar dan tipuan untuk mengingatkan kami bagaimana bahasa itu bekerja.

svidgen
sumber
6

Contoh Anda terlihat dibuat-buat. Dalam kode dunia nyata, fakta bahwa loop harus dimulai pada elemen array kedua sangat jelas dari baris kode berikut. Misalnya, jika kode aslinya terlihat seperti ini

for($i=1 ; $i < count(array) ; $i++){
    array[$i-1]=array[$i];
}

tidak akan ada penjelasan atau konstruksi "0 +1" yang diperlukan untuk menjelaskan mengapa loop dimulai pada 1 bukannya 0.

Namun, jika kode di dalam loop tidak menjelaskan alasan dengan cara yang jelas (mungkin array[0]memiliki makna khusus dan harus ditangani secara berbeda dari elemen yang tersisa), maka tambahkan komentar yang menjelaskan. Tetapi sebelum Anda melakukan ini, pikirkan dua kali jika Anda dapat menghindari memiliki array[0]makna khusus ini, dan mengatur ulang kode di sekitarnya, yang mungkin akan menjadi alternatif yang lebih baik.

Doc Brown
sumber
Dalam situasi seperti contoh kode Anda, saya ingin memberi nama variabel "oneBasedIndex" atau "zeroBasedIndex". Meskipun sesuatu yang lebih spesifik untuk tugas itu akan lebih baik.
user949300
5

Belum pernah melihat opsi # 2, tetapi saya menyukainya. Mengapa? Dengan opsi # 1 Saya ingin tahu apakah programmer lupa bahwa array mulai dari 0. Opsi # 2 membuatnya lebih jelas bahwa mereka sengaja mulai dari 1.

Yang mengatakan, lebih baik dalam kedua kasus untuk menambahkan komentar mengapa Anda melewatkan elemen.

Atau, jika Anda dapat dengan mudah menggambarkan mengapa Anda memulai pada satu, gunakan konstanta. Misalnya, jika melihat argumen baris perintah, sesuatu seperti

define ('FIRST_REAL_ARGUMENT', 1);
for ($i=FIRST_REAL_ARGUMENT; ...)

Secara pribadi, saya mungkin hanya menggunakan komentar saja, YMMV.

pengguna949300
sumber
Saya akan mengatakan bahwa di luar lingkungan di mana Anda berhadapan dengan pemula, saya tidak pernah memiliki masalah rekan kerja lupa bahwa array mulai dari nol. Saya bisa melihatnya terjadi jika pekerjaan Anda juga menggunakan bahasa seperti MATLAB, tetapi di sebagian besar lingkungan, saya berasumsi bahwa programmer tahu apa yang mereka lakukan. Dan heck, memulai loop pada 1 cukup umum. Ada beberapa alasan untuk melewatkan elemen pertama dari sesuatu.
Kat
@Kat Alasan itu perlu jelas bagi pembaca masa depan. Saya lebih suka berasumsi bahwa seorang programmer masa depan tidak tahu apa yang dilakukannya.
A1rPun
2

Saya ragu ada orang yang akan bingung dengan yang pertama. Kita semua harus melakukannya. Sedemikian rupa sehingga yang kedua lebih mungkin membingungkan. "Mengapa ada 0+ di sana? Apakah mereka menimpa + operator entah bagaimana?"

Kompilator yang layak akan mengubah yang kedua menjadi yang pertama, tetapi sepertinya Anda menggunakan PHP, yang ditafsirkan. Jadi, setiap kali penerjemah memukul lingkaran itu, itu harus benar-benar menambahkan 0 dan 1. Bukan masalah besar, tapi mengapa membuat penerjemah melakukan pekerjaan?

Kevin Fee
sumber
2

Gunakan variabel yang menjelaskan titik awal.

Anda perlu " melewati elemen pertama dalam array berbasis nol ", jadi misalnya:

skipFirstElement = 1;

for($i=$skipFirstElement ; $i < count(array) ; $i++){
    array[$i];
}
catta
sumber
6
Saya suka menggunakan variabel tetapi saya benci nama ini. Itu tidak menjelaskan MENGAPA Anda melewatkan elemen pertama. A 1 memberitahu saya itu. Apa bagusnya variabel yang perlu diganti namanya ketika nilainya berubah? Saya tahu OP tidak memberi kami petunjuk mengapa untuk memilih nama baik Anda harus membuat alasan. Tanpa nama yang lebih baik saya lebih suka memiliki 1 kembali.
candied_orange
@CandiedOrange Saya setuju dengan Anda bahwa nama variabel harus lebih bermakna, tetapi masalahnya seperti yang disajikan tidak menjelaskan mengapa ia ingin melewatkan nilai pertama. Maksud saya adalah, saya hanya memberi contoh, penulis bisa memilih nama yang terbaik untuknya.
catta
Tolong jangan mengajar dengan cara ini. Ini cukup membingungkan. Banyak coder akan meraih nama termudah yang mereka bisa sehingga mereka dapat kembali menulis sulit untuk memahami kode. Serius, saya lebih suka berurusan dengan 1 daripada ini.
candied_orange
1
//We are skipping the first element because...    
if ($i==0)  
{    continue;      } 

Jika seseorang terobsesi dengan semua loop mulai dari nol Anda bisa menggunakan pernyataan melanjutkan. Tambahkan komentar mengapa Anda melewatkannya karena biasanya tidak.

Jon Raynor
sumber
2
Masalah dengan opsi ini berarti bahwa kita akan mengevaluasi ini untuk setiap elemen tunggal, menambahkan n perbandingan tambahan ke loop, sementara hanya melewatkan yang pertama melalui beberapa metode lain (menggeser array, dimulai dengan i = 1, apa pun ) berarti hanya melakukan pekerjaan yang Anda butuhkan.
Kevin Fee
3
@KevinFee Jika Anda tidak berurusan dengan array besar, saya akan mengatakan perbandingan simle ini tidak akan menjadi masalah. Dan saya cukup suka dengan penjelasan if first then skipdengan komentar yang mengatakan mengapa. Masih tanpa konteks, tidak ada solusi yang "terbaik"
Ivan Pintar
-2

Apa yang akan saya lakukan adalah menghapus elemen pertama sebelum perulangan. Buat array baru jika perlu. Jelaskan dalam komentar mengapa Anda melakukannya. Dan kemudian hanya melakukan foreach sederhana.

$arrayCopy = $array; // in case you don't want to touch the original array
array_shift($arrayCopy); // removing first element because of X reason.
foreach($arrayCopy => $element) { 
    // do stuff
}

Dengan cara ini niat Anda sangat jelas.

Untuk memperjelas lebih lanjut Anda bisa membungkus kode dalam suatu metode dengan nama yang sesuai untuk memperjelas.

function doStuffToAllButTheFirst($array) { // this copies the original array, so there are no sideffects
    array_shift($array);
    foreach($array => $element) { // do stuff }  
}

Namun semua ini masih konteks yang hilang. Apa yang ingin Anda lakukan dengan elemen? Apakah Anda akan mengembalikan array baru? Apakah Anda peduli dengan yang asli dan yang baru setelah Anda doStuff()?

Bagaimanapun, tidak ada jawaban yang jelas di sini, dan memutuskan bagaimana membuat kode dapat dibaca sangat tergantung pada konteksnya.

Ivan Pintar
sumber
1
Saya suka ini karena saya tidak perlu berurusan dengan indeks sekarang, yang selalu merupakan nilai tambah.
Tomas Zubiri
1
Kerugiannya di sini adalah bahwa jika Anda tidak ingin efek samping, Anda perlu menyalin seluruh array.
Tomas Zubiri
1
Dan bagaimana jika alasan kita mulai dari 1 adalah karena kita melakukan $array[$i-1] = $array[$i]atau sesuatu yang serupa, sesuai jawaban @ DocBrown?
Kevin Fee
1
Ini tampak mengerikan bagiku. Selain semua inefisiensi, efek samping dan ketidakmampuan untuk menyelesaikan kasus penggunaan yang cukup umum untuk 1(lihat komentar Kevin Lee), itu tidak membuat kode lebih jelas sama sekali. Pembaca harus memahami array_shift, apa fungsinya, cara kerjanya. Mungkin baris kode ini adalah bug? Apakah itu memodifikasi array atau mengembalikan yang baru? Apakah itu memasukkan elemen atau menghapusnya? Apakah itu mengubah indeks atau tidak? Saya gagal melihat bagaimana menggunakan loop berbasis satu tidak akan menjadi peningkatan besar dalam fungsi itu (dan diberi namanya, langsung dapat dimengerti).
Eiko
1
Jawaban atas pertanyaan-pertanyaan ini sangat tergantung pada konteksnya. Dan untuk efisiensi, saya akan mengambil langkah awal untuk setiap hari ... Setiap perbedaan kinerja hampir tidak terlihat dalam kebanyakan kasus.
Ivan Pintar