Chuyển đổi danh sách C # <chuỗi> sang từ điển <chuỗi, chuỗi>


117

Điều này có vẻ là một điều kỳ lạ muốn làm nhưng bỏ qua điều đó, có một cách ngắn gọn hay ho để chuyển đổi Danh sách thành Từ điển trong đó mỗi Cặp giá trị khóa trong Từ điển chỉ là mỗi chuỗi trong Danh sách. I E

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

Tôi đã thực hiện rất nhiều tìm kiếm và có hàng tá ví dụ trên Stackoverflow một mình thực hiện theo hướng ngược lại nhưng không phải theo cách này.

Lý do để làm điều này là tôi có hai thành phần thứ ba và việc thay đổi chúng nằm ngoài tầm tay của tôi. Một cái trả về một danh sách các địa chỉ email dưới dạng Danh sách và cái còn lại gửi email trong đó tham số To là Từ điển. Chìa khóa của từ điển là địa chỉ email và giá trị là tên thật của họ. Tuy nhiên, tôi không biết tên thật nhưng nó vẫn hoạt động nếu bạn cũng đặt tên thật thành địa chỉ email. Vì vậy, tại sao tôi muốn chuyển đổi một danh sách thành một từ điển. Có rất nhiều cách để làm điều này. Một vòng lặp foreach trong danh sách có thêm kvp vào từ điển. Nhưng tôi thích mã terse và tự hỏi nếu có một giải pháp dòng duy nhất.


1
Tôi có một giải pháp tốt hơn cho lý do hợp lệ của bạn, trung thực.

2
Bạn có thể muốn xem Hashset <> có đáp ứng yêu cầu của bạn không, thay vì sử dụng Từ điển <,>.
Greg

Trực tiếp hơn những người bình luận ở trên: Nếu bạn giải thích lý do của bạn muốn điều này, có lẽ ai đó có thể đề xuất một giải pháp tốt hơn.
Tim S.

1
Không có giải pháp nào tốt hơn. Tôi có một thành phần bên thứ ba trả về một danh sách các chuỗi đó là các địa chỉ email. Tôi có một thành phần bên thứ ba khác gửi email trong đó nó chuyển từ điển <chuỗi, chuỗi> trong đó khóa là địa chỉ email và giá trị là tên thật của người nhận. Tuy nhiên, tên thật cũng có thể chỉ là địa chỉ email một lần nữa, đó là lý do tại sao tôi muốn chuyển đổi Danh sách <chuỗi> thành Từ điển <chuỗi, chuỗi>
Jonnster

Câu trả lời:


243

Thử cái này:

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

Lambda đầu tiên cho phép bạn chọn khóa, cái thứ hai chọn giá trị.

Bạn có thể chơi với nó và làm cho các giá trị khác với các phím, như thế này:

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

Nếu danh sách của bạn chứa các bản sao, hãy thêm Distinct()như thế này:

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

EDIT Để nhận xét về lý do hợp lệ, tôi nghĩ lý do duy nhất có thể hợp lệ cho các chuyển đổi như thế này là tại một số điểm, các khóa và giá trị trong từ điển kết quả sẽ bị phân kỳ. Ví dụ: bạn sẽ thực hiện chuyển đổi ban đầu và sau đó thay thế một số giá trị bằng thứ khác. Nếu các khóa và các giá trị luôn giống nhau, HashSet<String>sẽ cung cấp sự phù hợp tốt hơn cho tình huống của bạn:

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

điều này sẽ thất bại nếu danh sách giống như chuỗi1, chuỗi2, chuỗi3, chuỗi1
Pranay Rana

3
@PranayRana Vâng, nó sẽ như vậy. Bạn có thể thêm .Distinct()sau listđể tránh điều này.
dasblinkenlight

Cảm ơn. Tôi đã bỏ lỡ chức năng ToDipedia. Cảm ơn tất cả những người về cơ bản đã đưa ra câu trả lời giống nhau. Tôi ủng hộ tất cả mọi người nhưng chỉ có thể chấp nhận một câu trả lời. Cái này chỉ là một với mã riêng biệt được thêm vào nên theo tôi là đầy đủ nhất.
Jonnster

11

Dùng cái này:

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

Xem MSDN để biết thêm.

Như Pranay chỉ ra trong các bình luận, điều này sẽ thất bại nếu một mục tồn tại trong danh sách nhiều lần.
Tùy thuộc vào yêu cầu cụ thể của bạn, bạn có thể sử dụng var dict = list.Distinct().ToDictionary(x => x);để lấy từ điển các mục riêng biệt hoặc ToLookupthay vào đó bạn có thể sử dụng :

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

Điều này sẽ trả về một ILookup<string, string>cái về cơ bản giống như IDictionary<string, IEnumerable<string>>vậy, vì vậy bạn sẽ có một danh sách các khóa riêng biệt với mỗi thể hiện chuỗi bên dưới nó.


điều này sẽ thất bại nếu danh sách giống như chuỗi1, chuỗi2, chuỗi3, chuỗi1
Pranay Rana

1

Bằng cách sử dụng ToDictionary:

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

Nếu có thể lặp lại bất kỳ chuỗi nào, hãy thực hiện Distinct trước tiên hãy cuộc gọi trong danh sách (để loại bỏ trùng lặp) hoặc sử dụng ToLookupcho phép nhiều giá trị cho mỗi khóa.


0

Bạn có thể dùng:

var dictionary = myList.ToDictionary(x => x);

0

BIÊN TẬP

một cách khác để đối phó với trùng lặp là bạn có thể làm như thế này

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

hoặc là


cách dễ dàng để làm là

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

nhưng hãy chắc chắn rằng không có chuỗi nào lặp lại ... một lần nữa, đoạn mã trên sẽ không hoạt động với bạn

nếu có chuỗi lặp lại thì tốt hơn là làm như thế này

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

    foreach(string s in Stringlist)
    {
       if(!dic.ContainsKey(s))
       {
        //  dic.Add( value to dictionary
      }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.