C # แปลงรายการ <string> เป็นพจนานุกรม <string, string>


117

สิ่งนี้อาจดูเหมือนเป็นเรื่องแปลกที่อยากทำ แต่ไม่สนใจสิ่งนั้นมีวิธีที่กระชับที่ดีในการแปลงรายการเป็นพจนานุกรมโดยที่คู่ค่าคีย์แต่ละคู่ในพจนานุกรมเป็นเพียงแต่ละสตริงในรายการ กล่าวคือ

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

ฉันได้ทำการค้นหามากมายและมีตัวอย่างมากมายใน Stackoverflow เพียงอย่างเดียวในการทำในทิศทางตรงกันข้าม แต่ไม่ใช่วิธีนี้

เหตุผลในการทำเช่นนี้คือฉันมีส่วนประกอบของส่วนที่สามสองส่วนและการเปลี่ยนนั้นไม่อยู่ในมือฉัน หนึ่งส่งคืนรายการที่อยู่อีเมลเป็นรายการและอีกรายการหนึ่งส่งอีเมลโดยที่พารามิเตอร์ To คือ Dictionary คีย์ของพจนานุกรมคือที่อยู่อีเมลและค่าคือชื่อจริง อย่างไรก็ตามฉันไม่ทราบชื่อจริง แต่ยังคงใช้งานได้หากคุณตั้งชื่อจริงเป็นที่อยู่อีเมลด้วย เหตุใดฉันจึงต้องการแปลงรายการเป็นพจนานุกรม มีหลายวิธีในการทำเช่นนี้ foreach loop ในรายการซึ่งเพิ่ม kvp ลงในพจนานุกรม แต่ฉันชอบโค้ดสั้น ๆ และสงสัยว่ามีคำตอบแบบบรรทัดเดียวหรือไม่


1
ฉันมีทางออกที่ดีกว่าสำหรับเหตุผลที่ถูกต้องของคุณซื่อสัตย์

2
คุณอาจต้องการดูว่า HashSet <> ตรงตามความต้องการของคุณหรือไม่แทนที่จะใช้ Dictionary <,>
Greg

ตรงไปตรงมามากกว่าผู้แสดงความคิดเห็นด้านบน: หากคุณอธิบายเหตุผลที่ต้องการสิ่งนี้อาจมีคนแนะนำวิธีแก้ปัญหาที่ดีกว่าได้
Tim S.

1
ไม่มีทางออกที่ดีกว่านี้ ฉันมีองค์ประกอบของบุคคลที่สามที่ส่งคืนรายการสตริงเหล่านี้คือที่อยู่อีเมล ฉันมีส่วนประกอบของบุคคลที่สามอื่นที่ส่งอีเมลซึ่งส่งผ่าน Dictionary <string, string> โดยที่คีย์คือที่อยู่อีเมลและค่าคือชื่อจริงของผู้รับ อย่างไรก็ตามชื่อจริงยังสามารถเป็นที่อยู่อีเมลได้อีกด้วยซึ่งเป็นสาเหตุที่ฉันต้องการแปลง List <string> เป็น Dictionary <string, string>
Jonnster

คำตอบ:


244

ลองสิ่งนี้:

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

แลมบ์ดาตัวแรกให้คุณเลือกคีย์ตัวที่สองเลือกค่า

คุณสามารถเล่นกับมันและทำให้ค่าแตกต่างจากคีย์เช่นนี้:

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

หากรายการของคุณมีรายการที่ซ้ำกันให้เพิ่มDistinct()ดังนี้:

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

แก้ไขเพื่อแสดงความคิดเห็นเกี่ยวกับเหตุผลที่ถูกต้องฉันคิดว่าเหตุผลเดียวที่สามารถใช้ได้สำหรับการแปลงเช่นนี้ก็คือเมื่อถึงจุดหนึ่งคีย์และค่าในพจนานุกรมผลลัพธ์จะแตกต่างกัน ตัวอย่างเช่นคุณจะทำการแปลงครั้งแรกจากนั้นแทนที่ค่าบางค่าด้วยอย่างอื่น ถ้าคีย์และค่าจะถูกเสมอไปได้เหมือนกันHashSet<String>จะให้เป็นแบบที่ดีมากสำหรับสถานการณ์ของคุณ:

var res = new HashSet<string>(list);
if (res.Contains("string1")) ...

สิ่งนี้จะล้มเหลวหาก list เป็นเช่น string1, string2, string3, string1
Pranay Rana

3
@PranayRana ใช่มันจะ. คุณสามารถเพิ่ม.Distinct()หลังจากlistนี้เพื่อหลีกเลี่ยงปัญหานี้
dasblinkenlight

ขอบคุณ ฉันพลาดฟังก์ชัน ToDictionary ขอบคุณทุกคนที่ให้คำตอบเดียวกัน ฉันเพิ่มคะแนนให้ทุกคน แต่ยอมรับได้เพียงคำตอบเดียว อันนี้เป็นเพียงรหัสเดียวที่เพิ่มรหัสพิเศษดังนั้นจึงสมบูรณ์ที่สุดในความคิดของฉัน
Jonnster

11

ใช้สิ่งนี้:

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

ดูMSDNสำหรับข้อมูลเพิ่มเติม

ดังที่ Pranay ชี้ให้เห็นในความคิดเห็นสิ่งนี้จะล้มเหลวหากมีรายการอยู่ในรายการหลายครั้ง
ขึ้นอยู่กับความต้องการเฉพาะของคุณคุณสามารถใช้var dict = list.Distinct().ToDictionary(x => x);เพื่อรับพจนานุกรมของรายการที่แตกต่างกันหรือใช้ToLookupแทน:

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

สิ่งนี้จะส่งคืนILookup<string, string>ซึ่งโดยพื้นฐานแล้วจะเหมือนกับIDictionary<string, IEnumerable<string>>ดังนั้นคุณจะมีรายการคีย์ที่แตกต่างกันโดยมีอินสแตนซ์สตริงแต่ละรายการอยู่ข้างใต้


สิ่งนี้จะล้มเหลวหาก list เป็นเช่น string1, string2, string3, string1
Pranay Rana

1

โดยใช้ToDictionary:

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

หากเป็นไปได้ว่าสตริงใด ๆ สามารถทำซ้ำได้ให้ทำการDistinctโทรก่อนในรายการ (เพื่อลบรายการที่ซ้ำกัน) หรือใช้ToLookupซึ่งอนุญาตให้มีหลายค่าต่อคีย์



0

แก้ไข

อีกวิธีหนึ่งในการจัดการกับรายการที่ซ้ำกันคือคุณสามารถทำเช่นนี้ได้

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

หรือ


วิธีทำง่ายๆคือ

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

แต่ตรวจสอบให้แน่ใจว่าไม่มีสตริงซ้ำ ... อีกครั้งนอกจากนี้โค้ดด้านบนจะไม่ทำงานสำหรับคุณ

หากมีการทำซ้ำสตริงจะดีกว่าที่จะทำเช่นนี้

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

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.