Tôi đã thấy một vài cách khác nhau để lặp lại từ điển trong C #. Có một cách tiêu chuẩn?
Tôi đã thấy một vài cách khác nhau để lặp lại từ điển trong C #. Có một cách tiêu chuẩn?
Câu trả lời:
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
var entry
là tốt hơn trong trường hợp đó, và do đó tôi đã bỏ phiếu cho câu trả lời này trên giao diện thứ hai thay vì ở trên.
var
khi bạn không biết loại nói chung là thực tiễn xấu.
var
chỉ hoạt động nếu loại được biết tại thời gian biên dịch. Nếu Visual Studio biết loại này thì bạn cũng có thể tìm hiểu.
Nếu bạn đang cố gắng sử dụng Từ điển chung trong C # như bạn sẽ sử dụng một mảng kết hợp trong ngôn ngữ khác:
foreach(var item in myDictionary)
{
foo(item.Key);
bar(item.Value);
}
Hoặc, nếu bạn chỉ cần lặp lại bộ sưu tập các phím, hãy sử dụng
foreach(var item in myDictionary.Keys)
{
foo(item);
}
Và cuối cùng, nếu bạn chỉ quan tâm đến các giá trị:
foreach(var item in myDictionary.Values)
{
foo(item);
}
(Lưu ý rằng var
từ khóa là một tính năng tùy chọn C # 3.0 trở lên, bạn cũng có thể sử dụng loại khóa / giá trị chính xác của mình tại đây)
myDictionary
(trừ khi đó là tên thực tế của khóa học). Tôi nghĩ rằng sử dụng var là tốt khi loại này là rõ ràng, var x = "some string"
nhưng khi nó không rõ ràng ngay lập tức tôi nghĩ rằng việc mã hóa lười biếng làm tổn thương người đọc / đánh giá mã
var
Theo tôi nên sử dụng một cách tiết kiệm. Đặc biệt ở đây, nó không mang tính xây dựng: loại KeyValuePair
có khả năng liên quan đến câu hỏi.
var
có một mục đích duy nhất và tôi không tin đó là đường 'cú pháp'. Sử dụng nó có mục đích là một cách tiếp cận phù hợp.
Trong một số trường hợp, bạn có thể cần một bộ đếm có thể được cung cấp bằng cách thực hiện vòng lặp for. Do đó, LINQ cung cấp ElementAt
cho phép những điều sau đây:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
ElementAt
một hoạt động O (n)?
.ElementAt
trong bối cảnh này có thể dẫn đến các lỗi tinh vi. Nghiêm trọng hơn nhiều là quan điểm của Arturo ở trên. Bạn sẽ lặp lại số dictionary.Count + 1
lần từ điển dẫn đến độ phức tạp O (n ^ 2) cho một thao tác chỉ nên là O (n). Nếu bạn thực sự cần một chỉ mục (nếu có, có lẽ bạn đang sử dụng loại bộ sưu tập sai ở vị trí đầu tiên), bạn nên lặp lại dictionary.Select( (kvp, idx) => new {Index = idx, kvp.Key, kvp.Value})
thay thế và không sử dụng .ElementAt
bên trong vòng lặp.
Phụ thuộc vào việc bạn theo đuổi các khóa hay các giá trị ...
Từ Dictionary(TKey, TValue)
mô tả Lớp MSDN :
// When you use foreach to enumerate dictionary elements,
// the elements are retrieved as KeyValuePair objects.
Console.WriteLine();
foreach( KeyValuePair<string, string> kvp in openWith )
{
Console.WriteLine("Key = {0}, Value = {1}",
kvp.Key, kvp.Value);
}
// To get the values alone, use the Values property.
Dictionary<string, string>.ValueCollection valueColl =
openWith.Values;
// The elements of the ValueCollection are strongly typed
// with the type that was specified for dictionary values.
Console.WriteLine();
foreach( string s in valueColl )
{
Console.WriteLine("Value = {0}", s);
}
// To get the keys alone, use the Keys property.
Dictionary<string, string>.KeyCollection keyColl =
openWith.Keys;
// The elements of the KeyCollection are strongly typed
// with the type that was specified for dictionary keys.
Console.WriteLine();
foreach( string s in keyColl )
{
Console.WriteLine("Key = {0}", s);
}
Nói chung, yêu cầu "cách tốt nhất" mà không có bối cảnh cụ thể cũng giống như hỏi màu nào là tốt nhất ?
Một mặt, có nhiều màu sắc và không có màu nào đẹp nhất. Nó phụ thuộc vào nhu cầu và thường xuyên về hương vị, quá.
Mặt khác, có nhiều cách để lặp lại từ điển trong C # và không có cách nào tốt nhất. Nó phụ thuộc vào nhu cầu và thường xuyên về hương vị, quá.
foreach (var kvp in items)
{
// key is kvp.Key
doStuff(kvp.Value)
}
Nếu bạn chỉ cần giá trị (cho phép gọi nó item
, dễ đọc hơn kvp.Value
).
foreach (var item in items.Values)
{
doStuff(item)
}
Nói chung, người mới bắt đầu ngạc nhiên về thứ tự liệt kê của Từ điển.
LINQ cung cấp một cú pháp ngắn gọn cho phép chỉ định thứ tự (và nhiều thứ khác), ví dụ:
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
// key is kvp.Key
doStuff(kvp.Value)
}
Một lần nữa bạn có thể chỉ cần giá trị. LINQ cũng cung cấp một giải pháp ngắn gọn để:
item
, dễ đọc hơnkvp.Value
)Đây là:
foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
doStuff(item)
}
Có rất nhiều trường hợp sử dụng trong thế giới thực mà bạn có thể làm từ những ví dụ này. Nếu bạn không cần một đơn đặt hàng cụ thể, chỉ cần tuân theo "cách đơn giản nhất" (xem bên trên)!
.Values
và không phải là một mệnh đề chọn.
Value
trường. Loại chính xác tôi thấy ở đây là IOrderedEnumerable<KeyValuePair<TKey, TValue>>
. Có lẽ bạn có ý gì khác? Bạn có thể viết một dòng hoàn chỉnh cho thấy những gì bạn có ý nghĩa (và kiểm tra nó)?
items.Value
như bạn đề nghị. Trong trường hợp của phần thứ tư mà bạn nhận xét, đây Select()
là một cách gây ra foreach
để liệt kê trực tiếp các giá trị trong từ điển thay vì các cặp khóa-giá trị. Nếu bằng cách nào đó bạn không thích Select()
trong trường hợp này, bạn có thể thích phần mã thứ ba. Điểm của phần thứ tư là chỉ ra rằng người ta có thể xử lý trước bộ sưu tập với LINQ.
.Keys.Orderby()
sẽ lặp đi lặp lại trên một danh sách các khóa. Nếu đó là tất cả những gì bạn cần, tốt thôi. Nếu bạn cần các giá trị, thì trong vòng lặp bạn phải truy vấn từ điển trên mỗi khóa để lấy giá trị. Trong nhiều kịch bản, nó sẽ không tạo ra sự khác biệt thực tế. Trong kịch bản hiệu suất cao, nó sẽ. Giống như tôi đã viết ở đầu câu trả lời: "có nhiều cách (...) và không có cách nào tốt nhất. Nó phụ thuộc vào nhu cầu và thường là về hương vị."
Tôi muốn nói foreach là cách tiêu chuẩn, mặc dù nó rõ ràng phụ thuộc vào những gì bạn đang tìm kiếm
foreach(var kvp in my_dictionary) {
...
}
Có phải đó là những gì bạn đang tìm kiếm?
kvp
thường được sử dụng để đặt tên cho các phiên bản KeyValuePair khi lặp lại từ điển và cấu trúc dữ liệu liên quan : foreach(var kvp in myDictionary){...
.
C # 7.0 đã giới thiệu Deconstructor và nếu bạn đang sửdụng Ứng dụng .NET Core 2.0+ , cấu trúcKeyValuePair<>
đã bao gồm mộtDeconstruct()
cho bạn. Vì vậy, bạn có thể làm:
var dic = new Dictionary<int, string>() { { 1, "One" }, { 2, "Two" }, { 3, "Three" } };
foreach (var (key, value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
//Or
foreach (var (_, value) in dic) {
Console.WriteLine($"Item [NO_ID] = {value}");
}
//Or
foreach ((int key, string value) in dic) {
Console.WriteLine($"Item [{key}] = {value}");
}
foreach (var (key, value) in dic.Select(x => (x.Key, x.Value)))
Tôi đánh giá cao câu hỏi này đã có rất nhiều câu trả lời nhưng tôi muốn đưa vào một nghiên cứu nhỏ.
Lặp lại từ điển có thể khá chậm khi so sánh với lặp qua một cái gì đó như một mảng. Trong các thử nghiệm của tôi, một lần lặp trên một mảng mất 0,015003 giây trong khi một lần lặp trên một từ điển (có cùng số phần tử) mất 0,0365073 giây dài gấp 2,4 lần! Mặc dù tôi đã thấy sự khác biệt lớn hơn nhiều. Để so sánh, một Danh sách nằm ở khoảng giữa 0,00215043 giây.
Tuy nhiên, điều đó giống như so sánh táo và cam. Quan điểm của tôi là lặp đi lặp lại từ điển là chậm.
Từ điển được tối ưu hóa cho việc tra cứu, do đó, trong tâm trí tôi đã tạo ra hai phương pháp. Một người chỉ đơn giản là làm một bài giảng, người kia lặp lại các phím sau đó nhìn lên.
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
Cái này tải các khóa và lặp lại trên chúng thay vào đó (tôi cũng đã thử kéo các phím thành một chuỗi [] nhưng sự khác biệt là không đáng kể.
public static string Keys(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var key in dictionary.Keys)
{
value = dictionary[key];
count++;
}
return "Keys";
}
Với ví dụ này, bài kiểm tra foreach bình thường đã lấy 0,0310062 và phiên bản khóa mất 0,2205441. Tải tất cả các khóa và lặp đi lặp lại trên tất cả các tra cứu rõ ràng là rất chậm!
Đối với thử nghiệm cuối cùng, tôi đã thực hiện lặp đi lặp lại mười lần để xem liệu có bất kỳ lợi ích nào khi sử dụng các phím ở đây không (đến thời điểm này tôi chỉ tò mò):
Đây là phương pháp RunTest nếu điều đó giúp bạn hình dung những gì đang diễn ra.
private static string RunTest<T>(T dictionary, Func<T, string> function)
{
DateTime start = DateTime.Now;
string name = null;
for (int i = 0; i < 10; i++)
{
name = function(dictionary);
}
DateTime end = DateTime.Now;
var duration = end.Subtract(start);
return string.Format("{0} took {1} seconds", name, duration.TotalSeconds);
}
Ở đây, lần chạy foreach bình thường mất 0,2820564 giây (lâu hơn khoảng mười lần so với một lần lặp duy nhất - như bạn mong đợi). Lặp lại các phím mất 2,2249449 giây.
Đã chỉnh sửa để thêm: Đọc một số câu trả lời khác khiến tôi đặt câu hỏi điều gì sẽ xảy ra nếu tôi sử dụng Từ điển thay vì Từ điển. Trong ví dụ này, mảng mất 0,0120024 giây, danh sách 0,015037 giây và từ điển 0,0465093 giây. Thật hợp lý khi hy vọng rằng kiểu dữ liệu tạo ra sự khác biệt về mức độ chậm hơn của từ điển.
Kết luận của tôi là gì?
Có rất nhiều lựa chọn. Yêu thích cá nhân của tôi là bởi KeyValuePair
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary)
{
// Do some interesting things
}
Bạn cũng có thể sử dụng Bộ sưu tập Khóa và Giá trị
Với .NET Framework 4.7
một người có thể sử dụng phân hủy
var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
Console.WriteLine(fruit + ": " + number);
}
Để làm cho mã này hoạt động trên các phiên bản C # thấp hơn, hãy thêm System.ValueTuple NuGet package
và viết ở đâu đó
public static class MyExtensions
{
public static void Deconstruct<T1, T2>(this KeyValuePair<T1, T2> tuple,
out T1 key, out T2 value)
{
key = tuple.Key;
value = tuple.Value;
}
}
ValueTuple
được tích hợp sẵn. Nó có sẵn dưới dạng gói nuget cho các phiên bản trước. Quan trọng hơn, C # 7.0+ là cần thiết để Deconstruct
phương thức hoạt động như một công cụ giải mã cho var (fruit, number) in fruits
.
Kể từ C # 7, bạn có thể giải cấu trúc các đối tượng thành các biến. Tôi tin rằng đây là cách tốt nhất để lặp lại từ điển.
Thí dụ:
Tạo một phương thức mở rộng trên KeyValuePair<TKey, TVal>
đó giải mã nó:
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
key = pair.Key;
value = pair.Value;
}
Lặp lại bất kỳ Dictionary<TKey, TVal>
theo cách nào sau đây
// Dictionary can be of any types, just using 'int' and 'string' as examples.
Dictionary<int, string> dict = new Dictionary<int, string>();
// Deconstructor gets called here.
foreach (var (key, value) in dict)
{
Console.WriteLine($"{key} : {value}");
}
Bạn đề nghị dưới đây để lặp đi lặp lại
Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary) {
//Do some interesting things;
}
FYI, foreach
không hoạt động nếu giá trị thuộc loại đối tượng.
foreach
sẽ không hoạt động nếu có giá trị là loại object
? Nếu không thì điều này không có nhiều ý nghĩa.
Sử dụng C # 7 , thêm phương thức mở rộng này vào bất kỳ dự án nào của giải pháp của bạn:
public static class IDictionaryExtensions
{
public static IEnumerable<(TKey, TValue)> Tuples<TKey, TValue>(
this IDictionary<TKey, TValue> dict)
{
foreach (KeyValuePair<TKey, TValue> kvp in dict)
yield return (kvp.Key, kvp.Value);
}
}
Và sử dụng cú pháp đơn giản này
foreach (var(id, value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
Hoặc cái này, nếu bạn thích
foreach ((string id, object value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
Thay thế cho truyền thống
foreach (KeyValuePair<string, object> kvp in dict)
{
string id = kvp.Key;
object value = kvp.Value;
// your code using 'id' and 'value'
}
Phương thức mở rộng biến đổi KeyValuePair
của bạn IDictionary<TKey, TValue>
thành một kiểu gõ mạnhtuple
, cho phép bạn sử dụng cú pháp thoải mái mới này.
Nó chuyển đổi -just- các mục từ điển cần thiết thành tuples
, vì vậy nó KHÔNG chuyển đổi toàn bộ từ điển thànhtuples
, do đó không có mối quan tâm về hiệu suất liên quan đến điều đó.
Chỉ có một chi phí nhỏ khi gọi phương thức tiện ích mở rộng để tạo tuple
so sánh với việc sử dụng KeyValuePair
trực tiếp, điều này KHÔNG phải là vấn đề nếu bạn chỉ địnhKeyValuePair
thuộc tính Key
vàValue
cho các biến vòng lặp mới.
Trong thực tế, cú pháp mới này rất phù hợp với hầu hết các trường hợp, ngoại trừ các kịch bản hiệu suất cực cao ở mức độ thấp, trong đó bạn vẫn có tùy chọn đơn giản là không sử dụng nó vào vị trí cụ thể đó.
Hãy xem điều này: Blog MSDN - Các tính năng mới trong C # 7
kvp.Key
và kvp.Value
để sử dụng khóa và giá trị tương ứng. Với các bộ dữ liệu, bạn có thể linh hoạt đặt tên khóa và giá trị theo ý muốn mà không cần sử dụng các khai báo biến tiếp theo bên trong khối foreach. Ví dụ, bạn có thể đặt tên khóa của mình là factoryName
và giá trị là models
, đặc biệt hữu ích khi bạn nhận được các vòng lặp lồng nhau (từ điển của từ điển): bảo trì mã dễ dàng hơn nhiều. Chỉ cần cung cấp cho nó một thử! ;-)
Tôi biết đây là một câu hỏi rất cũ, nhưng tôi đã tạo ra một số phương pháp mở rộng có thể hữu ích:
public static void ForEach<T, U>(this Dictionary<T, U> d, Action<KeyValuePair<T, U>> a)
{
foreach (KeyValuePair<T, U> p in d) { a(p); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.KeyCollection k, Action<T> a)
{
foreach (T t in k) { a(t); }
}
public static void ForEach<T, U>(this Dictionary<T, U>.ValueCollection v, Action<U> a)
{
foreach (U u in v) { a(u); }
}
Bằng cách này tôi có thể viết mã như thế này:
myDictionary.ForEach(pair => Console.Write($"key: {pair.Key}, value: {pair.Value}"));
myDictionary.Keys.ForEach(key => Console.Write(key););
myDictionary.Values.ForEach(value => Console.Write(value););
Đôi khi nếu bạn chỉ cần liệt kê các giá trị, hãy sử dụng bộ sưu tập giá trị của từ điển:
foreach(var value in dictionary.Values)
{
// do something with entry.Value only
}
Báo cáo bởi bài đăng này trong đó nêu rõ đây là phương pháp nhanh nhất: http://alapiinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html
Tôi đã tìm thấy phương thức này trong tài liệu cho lớp DictionaryBase trên MSDN:
foreach (DictionaryEntry de in myDictionary)
{
//Do some stuff with de.Value or de.Key
}
Đây là người duy nhất tôi có thể hoạt động chính xác trong một lớp được kế thừa từ DictionaryBase.
Hashtable
các đối tượng
ContainsKey()
trong for
phiên bản? Điều đó bổ sung thêm chi phí không có trong mã mà bạn đang so sánh. TryGetValue()
tồn tại để thay thế chính xác mẫu "nếu khóa tồn tại, lấy vật phẩm bằng khóa". Hơn nữa, nếu dict
chứa một phạm vi số nguyên liền kề từ 0
đến dictCount - 1
, bạn biết rằng bộ chỉ mục không thể thất bại; nếu không, dict.Keys
là những gì bạn nên lặp đi lặp lại. Dù bằng cách nào, không ContainsKey()
/ TryGetValue()
cần thiết. Cuối cùng, xin vui lòng không đăng ảnh chụp màn hình của mã.
Tôi đã viết một phần mở rộng để lặp qua một từ điển.
public static class DictionaryExtension
{
public static void ForEach<T1, T2>(this Dictionary<T1, T2> dictionary, Action<T1, T2> action) {
foreach(KeyValuePair<T1, T2> keyValue in dictionary) {
action(keyValue.Key, keyValue.Value);
}
}
}
Sau đó bạn có thể gọi
myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));
ForEach
phương thức mà bạn có foreach (...) { }
... Có vẻ như không cần thiết.
Nếu nói, bạn muốn lặp lại bộ sưu tập giá trị theo mặc định, tôi tin rằng bạn có thể triển khai IEnumerable <>, trong đó T là loại đối tượng giá trị trong từ điển và "đây" là Từ điển.
public new IEnumerator<T> GetEnumerator()
{
return this.Values.GetEnumerator();
}
Chỉ muốn thêm 2 xu của tôi, vì hầu hết các câu trả lời liên quan đến vòng lặp foreach. Xin vui lòng, hãy xem mã sau đây:
Dictionary<String, Double> myProductPrices = new Dictionary<String, Double>();
//Add some entries to the dictionary
myProductPrices.ToList().ForEach(kvP =>
{
kvP.Value *= 1.15;
Console.Writeline(String.Format("Product '{0}' has a new price: {1} $", kvp.Key, kvP.Value));
});
Đã đọc điều này thêm một lệnh gọi '.ToList ()', có thể có một sự cải thiện hiệu suất nhỏ (như được chỉ ra ở đây foreach vs someList.Foreach () {} ), đặc biệt khi làm việc với Từ điển lớn và chạy song song là không tùy chọn / sẽ không có hiệu lực nào cả.
Ngoài ra, xin lưu ý rằng bạn sẽ không thể gán giá trị cho thuộc tính 'Giá trị' bên trong vòng lặp foreach. Mặt khác, bạn cũng có thể điều khiển 'Khóa', có thể khiến bạn gặp rắc rối khi chạy.
Khi bạn chỉ muốn "đọc" Khóa và Giá trị, bạn cũng có thể sử dụng IEnumerable.Select ().
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
foreach
buộc khả năng hiển thị hiệu ứng phụ lên, nơi nó thuộc về.
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
AggregateObject
thêm KeyValuePair
gì? Trường hợp "lặp lại", như được yêu cầu trong câu hỏi?
foreach
, nhưng tôi đã sử dụng nó rất nhiều. Có phải câu trả lời của tôi thực sự xứng đáng downvote?
Select
sử dụng phép lặp để tạo kết quả, nhưng bản thân nó không phải là trình lặp. Các loại điều mà phép lặp ( foreach
) được sử dụng cho - đặc biệt là các hoạt động có tác dụng phụ - nằm ngoài phạm vi của Linq, bao gồm Select
. Lambda sẽ không chạy cho đến khi aggregateObjectCollection
thực sự được liệt kê. Nếu câu trả lời này được coi là "con đường đầu tiên" (nghĩa là được sử dụng trước một đường thẳng foreach
) thì nó khuyến khích các thực hành xấu. Về mặt tình huống, có thể các hoạt động Linq hữu ích trước khi lặp lại từ điển, nhưng điều đó không giải quyết được câu hỏi như đã hỏi.
Từ điển <TKey, TValue> Đây là lớp tập hợp chung trong c # và nó lưu trữ dữ liệu ở định dạng giá trị khóa. Khóa phải là duy nhất và không thể là null trong khi giá trị có thể trùng lặp và null. Mỗi mục trong từ điển là được coi là cấu trúc KeyValuePair <TKey, TValue> đại diện cho một khóa và giá trị của nó. và do đó chúng ta nên lấy loại phần tử KeyValuePair <TKey, TValue> trong quá trình lặp lại của phần tử. Dưới đây là ví dụ.
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1,"One");
dict.Add(2,"Two");
dict.Add(3,"Three");
foreach (KeyValuePair<int, string> item in dict)
{
Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);
}
Nếu bạn muốn sử dụng cho vòng lặp, bạn có thể làm điều này:
var keyList=new List<string>(dictionary.Keys);
for (int i = 0; i < keyList.Count; i++)
{
var key= keyList[i];
var value = dictionary[key];
}
foreach
vòng lặp và hiệu suất kém hơn bởi vì new List<string>(dictionary.Keys)
sẽ lặp lại dictionary.Count
nhiều lần trước khi bạn thậm chí có cơ hội lặp lại chính nó. Đặt sang một bên rằng yêu cầu "cách tốt nhất" là chủ quan, tôi không thấy cách này sẽ đủ điều kiện là "cách tốt nhất" hoặc "cách tiêu chuẩn" mà câu hỏi tìm kiếm. Để "Nếu bạn muốn sử dụng cho vòng lặp ..." Tôi sẽ truy cập bằng " Đừng sử dụng for
vòng lặp."
foreach (var pair in dictionary.ToArray()) { }
. Tuy nhiên, tôi nghĩ sẽ tốt hơn nếu làm rõ trong câu trả lời (các) kịch bản cụ thể mà người ta muốn sử dụng mã này và ý nghĩa của việc làm như vậy.
Như đã chỉ ra trong câu trả lời này , KeyValuePair<TKey, TValue>
thực hiện một Deconstruct
phương thức bắt đầu trên .NET Core 2.0, .NET Standard 2.1 và .NET Framework 5.0 (xem trước).
Với điều này, có thể lặp lại từ điển KeyValuePair
theo cách bất khả tri:
var dictionary = new Dictionary<int, string>();
// ...
foreach (var (key, value) in dictionary)
{
// ...
}
đơn giản với linq
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "American Ipa");
dict.Add(2, "Weiss");
dict.ToList().ForEach(x => Console.WriteLine($"key: {x.Key} | value: {x.Value}") );
ToList()
bởi vì ForEach()
chỉ được xác định trên List<>
lớp, nhưng tại sao làm tất cả điều đó thay vì chỉ foreach (var pair in dict) { }
? Tôi muốn nói rằng điều đó thậm chí còn đơn giản hơn và không có cùng hàm ý về bộ nhớ / hiệu năng. Giải pháp chính xác này đã được đề xuất trong câu trả lời này từ 3,5 năm trước, dù sao đi nữa.
ngoài các bài đăng xếp hạng cao nhất, nơi có một cuộc thảo luận giữa việc sử dụng
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
hoặc là
foreach(var entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
Hoàn thiện nhất là như sau vì bạn có thể thấy loại từ điển từ khi khởi tạo, kvp là KeyValuePair
var myDictionary = new Dictionary<string, string>(x);//fill dictionary with x
foreach(var kvp in myDictionary)//iterate over dictionary
{
// do something with kvp.Value or kvp.Key
}