Saya memiliki foreach
loop dan perlu menjalankan beberapa logika ketika item terakhir dipilih dari List
, misalnya:
foreach (Item result in Model.Results)
{
//if current result is the last item in Model.Results
//then do something in the code
}
Bisakah saya tahu loop mana yang terakhir tanpa menggunakan loop dan counter?
Jawaban:
Jika Anda hanya perlu melakukan sesuatu dengan elemen terakhir (sebagai lawan dari sesuatu yang berbeda dengan elemen terakhir kemudian menggunakan LINQ akan membantu di sini:
Jika Anda perlu melakukan sesuatu yang berbeda dengan elemen terakhir maka Anda akan membutuhkan sesuatu seperti:
Meskipun Anda mungkin harus menulis pembanding khusus untuk memastikan bahwa Anda dapat mengetahui bahwa item tersebut sama dengan item yang dikembalikan oleh
Last()
.Pendekatan ini harus digunakan dengan hati-hati karena
Last
mungkin harus dilakukan berulang kali melalui pengumpulan. Meskipun ini mungkin bukan masalah untuk koleksi kecil, jika menjadi besar itu bisa memiliki implikasi kinerja. Ini juga akan gagal jika daftar berisi item duplikat. Dalam hal ini sesuatu seperti ini mungkin lebih tepat:sumber
var last = Model.Result[Model.Result.Count - 1];
untuk lebih cepat daripada menggunakanLast()
Bagaimana kalau kuno yang bagus untuk loop?
Atau menggunakan Linq dan foreach:
sumber
Model.Results
adaIEnumerable
. Anda dapat memanggilCount()
sebelum loop tetapi itu dapat menyebabkan iterasi penuh dari urutan.Menggunakan
Last()
pada tipe tertentu akan berulang melalui seluruh koleksi!Artinya, jika Anda membuat
foreach
dan meneleponLast()
, Anda memutar dua kali! yang saya yakin ingin Anda hindari dalam koleksi besar.Maka solusinya adalah menggunakan
do while
loop:Jadi kecuali jenis koleksi adalah tipe
IList<T>
yangLast()
fungsi akan iterate melalui semua elemen koleksi.Uji
Jika koleksi Anda menyediakan akses acak (mis. Implement
IList<T>
), Anda juga dapat memeriksa item Anda sebagai berikut.sumber
using
pernyataan? Saya pikir itu hanya diperlukan jika sebuah objek menangani sumber daya sistem operasi, tetapi tidak untuk struktur data yang dikelola.Seperti yang ditunjukkan Chris, Linq akan bekerja; cukup gunakan Last () untuk mendapatkan referensi ke yang terakhir di enumerable, dan selama Anda tidak bekerja dengan referensi itu maka lakukan kode normal Anda, tetapi jika Anda bekerja dengan referensi itu maka lakukan hal tambahan Anda. Kelemahannya adalah bahwa ia akan selalu menjadi kompleksitas O (N).
Anda bisa menggunakan Count () (yang merupakan O (1) jika IEnumerable juga merupakan ICollection; ini berlaku untuk sebagian besar IEnumerables built-in yang umum), dan hybrid foreach Anda dengan counter:
sumber
sumber
foreach
blokir. Seperti ini:var lastItem = objList.LastOrDeafault();
. Kemudian dari bagian dalamforeach
lingkaran Anda bisa memeriksa dengan cara ini:f (item.Equals(lastItem)) { ... }
. Dalam jawaban asli Anda,objList.LastOrDefault()
akan beralih ke koleksi di setiap iterasi "foreach" ( kompleksitas Polinomial terlibat ).Seperti yang ditunjukkan Shimmy, menggunakan Last () dapat menjadi masalah kinerja, misalnya jika koleksi Anda adalah hasil langsung dari ekspresi LINQ. Untuk mencegah beberapa iterasi, Anda bisa menggunakan metode ekstensi "ForEach" seperti ini:
Metode ekstensi terlihat seperti ini (sebagai bonus tambahan, itu juga akan memberi tahu Anda indeks dan jika Anda melihat elemen pertama):
sumber
Meningkatkan jawaban Daniel Wolf lebih jauh lagi Anda bisa menumpuk di yang lain
IEnumerable
untuk menghindari beberapa iterasi dan lambda seperti:Implementasi metode ekstensi:
sumber
foreach
, yang merupakan peningkatan.Implementasi iterator tidak menyediakan itu. Koleksi Anda mungkin yang dapat
IList
diakses melalui indeks di O (1). Dalam hal ini Anda dapat menggunakanfor
-loop normal :Jika Anda mengetahui jumlah, tetapi tidak dapat mengakses melalui indeks (dengan demikian, hasilnya adalah
ICollection
), Anda dapat menghitung sendiri dengan menambahkan sebuahi
diforeach
tubuh dan membandingkannya dengan panjang.Semua ini tidak sepenuhnya elegan. Solusi Chris mungkin yang terbaik yang pernah saya lihat sejauh ini.
sumber
Bagaimana dengan pendekatan yang lebih sederhana.
sumber
Pendekatan terbaik mungkin hanya akan menjalankan langkah itu setelah loop: misalnya
Atau jika Anda perlu melakukan sesuatu untuk hasil terakhir
sumber
Jawaban yang diterima tidak akan berfungsi untuk duplikat dalam koleksi. Jika Anda diatur pada
foreach
, Anda bisa menambahkan variabel pengindeksan Anda sendiri.sumber
menggunakan Linq dan foreach:
https://code.i-harness.com/en/q/7213ce
sumber
".Last ()" tidak berfungsi untuk saya, jadi saya harus melakukan sesuatu seperti ini:
sumber
Membuat beberapa penyesuaian kecil pada kode excelent dari Jon Skeet, Anda bahkan dapat membuatnya lebih pintar dengan memungkinkan akses ke item sebelumnya dan berikutnya. Tentu saja ini berarti Anda harus membaca dulu 1 item dalam implementasi. Untuk alasan kinerja, item sebelumnya dan berikutnya hanya dipertahankan untuk item iterasi saat ini. Bunyinya seperti ini:
sumber
Cara mengonversi
foreach
untuk bereaksi ke elemen terakhir:sumber
Hanya menyimpan nilai sebelumnya dan bekerja dengannya di dalam loop. Kemudian pada akhirnya nilai 'sebelumnya' akan menjadi item terakhir, membiarkan Anda menanganinya secara berbeda. Tidak diperlukan penghitungan atau perpustakaan khusus.
sumber
Anda bisa menggunakan for for loop dan tidak perlu menambahkan ekstra
if
di dalamfor
tubuh:The
-1
dalamfor
kondisi mengurus melewatkan item terakhir.sumber
Jon Skeet membuat a
SmartEnumerable<T>
jenis waktu yang lalu untuk menyelesaikan masalah yang tepat ini. Anda dapat melihat implementasinya di sini:http://codeblog.jonskeet.uk/2007/07/27/smart-enumerations/
Untuk mengunduh: http://www.yoda.arachsys.com/csharp/miscutil/
sumber
Untuk melakukan sesuatu yang tambahan untuk setiap elemen kecuali yang terakhir, pendekatan berbasis fungsi dapat digunakan.
Pendekatan ini memiliki kelemahan yang jelas: kurang kejelasan kode untuk kasus yang lebih kompleks. Memanggil delegasi mungkin tidak terlalu efektif. Pemecahan masalah mungkin tidak mudah. Sisi baiknya - coding itu menyenangkan!
Karena itu, saya akan menyarankan menggunakan polos untuk loop dalam kasus sepele, jika Anda tahu bahwa jumlah koleksi Anda tidak terlalu lambat.
sumber
Cara lain, yang tidak saya lihat diposting, adalah dengan menggunakan Antrian. Ini analog dengan cara mengimplementasikan metode SkipLast () tanpa mengulangi lebih dari yang diperlukan. Cara ini juga akan memungkinkan Anda melakukan ini pada sejumlah item terakhir.
Untuk memanggil ini Anda akan melakukan hal berikut:
sumber
sumber
Anda dapat membuat metode ekstensi yang didedikasikan khusus untuk ini:
dan Anda dapat menggunakannya seperti ini:
sumber
Berdasarkan pada tanggapan Shimmy, saya menciptakan metode ekstensi yang merupakan solusi yang semua orang inginkan. Ini sederhana, mudah digunakan, dan hanya mengulang koleksi sekali.
Ini bekerja pada siapa saja
IEnumerable<T>
. Penggunaannya terlihat seperti ini:Outputnya seperti:
Selain itu, Anda dapat menjadikan ini sebagai
Select
metode gaya. Kemudian, gunakan kembali ekstensi itu diForEach
. Kode itu terlihat seperti ini:sumber
Kami dapat memeriksa item terakhir dalam lingkaran.
sumber
sumber
Anda bisa melakukan ini:
sumber