C # Ubah Daftar <string> ke Kamus <string, string>

117

Ini mungkin tampak aneh untuk dilakukan tetapi mengabaikannya, adakah cara ringkas yang bagus untuk mengonversi Daftar ke Kamus di mana setiap Pasangan Nilai Kunci dalam Kamus hanyalah setiap string dalam Daftar. yaitu

List = string1, string2, string3
Dictionary = string1/string1, string2/string2, string3/string3

Saya telah melakukan banyak pencarian dan ada lusinan contoh di Stackoverflow yang melakukannya ke arah yang berlawanan tetapi tidak dengan cara ini.

Alasan untuk melakukan ini adalah saya memiliki dua komponen bagian ketiga dan mengubahnya di luar kendali saya. Satu mengembalikan daftar alamat email sebagai Daftar dan yang lainnya mengirim email di mana parameter Ke adalah Kamus. Kunci kamusnya adalah alamat email dan nilainya adalah nama aslinya. Namun, saya tidak tahu nama aslinya tetapi masih berfungsi jika Anda juga menyetel nama asli ke alamat email. Oleh karena itu mengapa saya ingin mengonversi Daftar ke Kamus. Ada banyak cara untuk melakukan ini. Perulangan foreach pada daftar yang menambahkan kvp ke kamus. Tapi saya suka kode singkat dan bertanya-tanya apakah ada solusi baris tunggal.

Jonnster
sumber
1
Saya punya solusi yang lebih baik untuk alasan valid Anda, jujur.
2
Anda mungkin ingin melihat apakah HashSet <> memenuhi persyaratan Anda, daripada menggunakan Kamus <,>.
Greg
Lebih langsung dari pemberi komentar di atas: Jika Anda menjelaskan alasan Anda menginginkan ini, seseorang mungkin dapat menyarankan solusi yang lebih baik.
Tim S.
1
Tidak ada solusi yang lebih baik. Saya memiliki komponen pihak ketiga yang mengembalikan daftar string ini adalah alamat email. Saya memiliki komponen pihak ketiga lain yang mengirim email yang melewati Dictionary <string, string> di mana kuncinya adalah alamat email dan nilainya adalah nama asli penerima. Namun, nama aslinya juga bisa menjadi alamat email lagi itulah sebabnya saya ingin mengonversi List <string> menjadi Dictionary <string, string>
Jonnster

Jawaban:

244

Coba ini:

var res = list.ToDictionary(x => x, x => x);

Lambda pertama memungkinkan Anda memilih kunci, yang kedua memilih nilainya.

Anda dapat bermain dengannya dan membuat nilai berbeda dari kunci, seperti ini:

var res = list.ToDictionary(x => x, x => string.Format("Val: {0}", x));

Jika daftar Anda berisi duplikat, tambahkan Distinct()seperti ini:

var res = list.Distinct().ToDictionary(x => x, x => x);

EDIT Untuk mengomentari alasan yang valid, saya pikir satu-satunya alasan yang dapat valid untuk konversi seperti ini adalah bahwa pada titik tertentu kunci dan nilai dalam kamus yang dihasilkan akan menyimpang. Misalnya, Anda akan melakukan konversi awal, lalu mengganti beberapa nilai dengan yang lain. Jika kunci dan nilainya selalu sama, HashSet<String>akan memberikan kesesuaian yang lebih baik untuk situasi Anda:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...
dasblinkenlight
sumber
ini akan gagal jika daftar seperti string1, string2, string3, string1
Pranay Rana
3
@PranayRana Ya, itu akan. Anda dapat menambahkan .Distinct()setelah listuntuk menghindari ini.
dasblinkenlight
Terima kasih. Saya melewatkan fungsi ToDictionary. Terima kasih kepada semua orang yang pada dasarnya memberikan jawaban yang sama. Saya memuji semua orang tetapi hanya dapat menerima satu jawaban. Yang ini hanya satu dengan penambahan kode Distinct jadi paling lengkap menurut saya.
Jonnster
11

Gunakan ini:

var dict = list.ToDictionary(x => x);

Lihat MSDN untuk info lebih lanjut.

Seperti yang ditunjukkan Pranay di komentar, ini akan gagal jika item ada dalam daftar beberapa kali.
Bergantung pada kebutuhan spesifik Anda, Anda dapat menggunakan var dict = list.Distinct().ToDictionary(x => x);untuk mendapatkan kamus item yang berbeda atau Anda dapat menggunakan ToLookupsebagai gantinya:

var dict = list.ToLookup(x => x);

Ini akan mengembalikan ILookup<string, string>yang pada dasarnya sama dengan IDictionary<string, IEnumerable<string>>, jadi Anda akan memiliki daftar kunci yang berbeda dengan setiap contoh string di bawahnya.

Daniel Hilgarth
sumber
ini akan gagal jika daftar seperti string1, string2, string3, string1
Pranay Rana
1

Dengan menggunakan ToDictionary:

var dictionary = list.ToDictionary(s => s);

Jika ada kemungkinan string apa pun dapat diulang, lakukan Distinctpanggilan terlebih dahulu pada daftar (untuk menghapus duplikat), atau gunakan ToLookupyang memungkinkan beberapa nilai per kunci.

Lukazoid
sumber
0

Kamu bisa memakai:

var dictionary = myList.ToDictionary(x => x);
dtsg
sumber
0

EDIT

Cara lain untuk menangani duplikat adalah Anda dapat melakukan seperti ini

var dic = slist.Select((element, index)=> new{element,index} )
            .ToDictionary(ele=>ele.index.ToString(), ele=>ele.element);

atau


cara mudah untuk melakukannya adalah

var res = list.ToDictionary(str => str, str=> str); 

tetapi pastikan tidak ada string yang berulang ... lagi-lagi karena kode di atas tidak akan berfungsi untuk Anda

Jika ada string yang berulang daripada lebih baik melakukan seperti ini

Dictionary<string,string> dic= new Dictionary<string,string> ();

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Pranay Rana
sumber