Jika saya menafsirkan pertanyaan Anda dengan benar, Anda mengatakan bahwa Anda menginginkan cara untuk menerapkan fungsi Anda ke daftar indeks, bukan satu indeks pada satu waktu.
Cara paling sederhana yang dapat saya lakukan untuk melakukan ini adalah dengan membuat fungsi lain yang disebut deleteElems
alih-alih deleteElem
(perhatikan akhiran s
.)
deleteElems
akan bertipe [Int] -> [a] -> [a]
dan akan memanggil setiap indeks.
CATATAN: Lihat PEMBARUAN di bagian bawah untuk solusi yang benar (Saya meninggalkan bagian ini di sini sehingga orang lain dapat belajar dari upaya awal saya untuk memecahkan masalah dan mengapa hal itu salah.)
Inilah salah satu cara untuk melakukannya:
deleteElems xs zs = foldr (\x z -> deleteElem x z) zs xs
yang dapat disingkat menjadi:
deleteElems xs zs = foldr deleteElem zs xs
Prelude> deleteElems [2,3] [1..10]
[1,4,5,6,7,8,9,10]
atau dari contoh Anda:
Prelude> map (deleteElems [2,3]) [["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"], ["hello", "whatever", "foo", "bar"]]
[["hello","bar"],["hello","bar"],["hello","bar"],["hello","bar"]]
deleteElems
menggunakan foldr
untuk memanggil deleteElem
berulang kali guna menghapus indeks di xs
dari zs
. Untuk penjelasan lebih mendalam tentang foldr
, lihat Bagaimana cara kerjafoldr?.
PEMBARUAN:
Sesuai komentar, implementasi deleteElems
di atas sebenarnya salah karena ketika diberikan daftar indeks, katakanlah [2,4,6]
, pertama-tama ia akan menghapus indeks 2
, mengembalikan daftar baru, kemudian menghapus indeks 4
pada daftar baru dan kembalikan daftar yang lebih baru, lalu hapus indeks 6
pada daftar yang lebih baru. Proses ini tidak komutatif, artinya mengubah urutan indeks, atau memberikan deleteElems
indeks [6,4,2]
tidak akan menghasilkan hal yang sama.
Saya memiliki cara untuk mendapatkan perilaku yang diantisipasi (menghapus indeks yang diberikan dari daftar asli) menggunakan fungsi intersect
dari Data.List
:
deleteElems xs zs = foldr1 intersect $ map ($ zs) $ map deleteElem xs
Versi baru deleteElems
ini menerapkan deleteElem
menggunakan setiap indeks di xs
, membuat daftar length xs
jumlah daftar fungsi deleteElem
yang dimasukkan ke setiap indeks tertentu. Kemudian map ($ zs)
menerapkan masing-masing fungsi deleteElem
kari ke zs
, menghasilkan daftar daftar, di mana setiap daftar bagian dalam hanya deleteElem
diterapkan ke salah satu indeks dan zs
. Terakhir, kami menggunakan intersect
dari Data.List
untuk menemukan daftar dengan semua elemen yang benar telah dihapus.
Selain itu, saya tetap merekomendasikan untuk memeriksa Bagaimana cara kerjafoldr?.
person
DJG
schedule
25.09.2013