मैंने C # में एक शब्दकोश पर पुनरावृति करने के लिए कुछ अलग तरीके देखे हैं। क्या कोई मानक तरीका है?
मैंने C # में एक शब्दकोश पर पुनरावृति करने के लिए कुछ अलग तरीके देखे हैं। क्या कोई मानक तरीका है?
जवाबों:
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
var entry
उस मामले में बेहतर है, और इस प्रकार मैंने इस उत्तर को उपरोक्त के बजाय एक दूसरे लुक पर वोट दिया ।
var
जब आप नहीं जानते कि प्रकार आम तौर पर बुरा अभ्यास है।
var
केवल तभी काम करता है जब प्रकार संकलित समय पर जाना जाता है। यदि Visual Studio प्रकार जानता है तो यह आपके लिए भी उपलब्ध है।
यदि आप C # में एक सामान्य शब्दकोश का उपयोग करने का प्रयास कर रहे हैं तो जैसे आप किसी अन्य भाषा में एक सहयोगी सरणी का उपयोग करेंगे:
foreach(var item in myDictionary)
{
foo(item.Key);
bar(item.Value);
}
या, यदि आपको केवल कुंजी के संग्रह पर पुनरावृति करने की आवश्यकता है, तो उपयोग करें
foreach(var item in myDictionary.Keys)
{
foo(item);
}
और अंत में, यदि आप केवल मूल्यों में रुचि रखते हैं:
foreach(var item in myDictionary.Values)
{
foo(item);
}
(ध्यान रखें कि var
कीवर्ड एक वैकल्पिक C # 3.0 और ऊपर की सुविधा है, आप अपनी कुंजी / मानों के सटीक प्रकार का भी उपयोग कर सकते हैं)
myDictionary
( प्रकार का वास्तविक नाम जब तक) प्रकार निर्धारित करने के लिए कोड के चारों ओर कूदना होगा । मुझे लगता है कि var का उपयोग करना अच्छा है, जब प्रकार स्पष्ट है जैसे, var x = "some string"
लेकिन जब यह तुरंत स्पष्ट नहीं होता है, तो मुझे लगता है कि यह आलसी कोडिंग है जो कोड रीडर / समीक्षक को चोट पहुंचाता है
var
मेरी राय में, संयम से इस्तेमाल किया जाना चाहिए। विशेष रूप से यहां, यह रचनात्मक नहीं है: प्रकार KeyValuePair
प्रश्न की संभावना है।
var
एक अनूठा उद्देश्य है और मुझे विश्वास नहीं है कि यह 'सिंटैक्टिक' चीनी है। उद्देश्यपूर्ण तरीके से इसका उपयोग करना एक उपयुक्त दृष्टिकोण है।
कुछ मामलों में आपको एक काउंटर की आवश्यकता हो सकती है जो लूप कार्यान्वयन के लिए प्रदान किया जा सकता है। उसके लिए, LINQ प्रदान करता है ElementAt
जो निम्नलिखित को सक्षम करता है :
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
ElementAt
एक हे (एन) आपरेशन?
.ElementAt
इस संदर्भ में उपयोग करने से सूक्ष्म कीड़े हो सकते हैं। अधिक गंभीर है Arturo के ऊपर बिंदु। आप dictionary.Count + 1
एक ऑपरेशन के लिए O (n ^ 2) जटिलता के लिए अग्रणी शब्दकोश की पुनरावृत्ति करेंगे जो केवल O (n) होना चाहिए। यदि आपको वास्तव में एक सूचकांक की आवश्यकता है (यदि आप करते हैं, तो आप शायद पहले स्थान पर गलत संग्रह प्रकार का उपयोग कर रहे हैं), आपको dictionary.Select( (kvp, idx) => new {Index = idx, kvp.Key, kvp.Value})
इसके बजाय पुनरावृति करना चाहिए और .ElementAt
लूप के अंदर उपयोग नहीं करना चाहिए ।
निर्भर करता है कि आप कुंजियों या मूल्यों के बाद हैं ...
MSDN Dictionary(TKey, TValue)
वर्ग विवरण से:
// 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);
}
आम तौर पर, एक विशिष्ट संदर्भ के बिना "सबसे अच्छा तरीका" के लिए पूछना यह पूछने के समान है कि सबसे अच्छा रंग क्या है ?
एक हाथ, कई रंग हैं और कोई सबसे अच्छा रंग नहीं है। यह जरूरत पर निर्भर करता है और अक्सर स्वाद पर भी।
दूसरी ओर, C # में एक शब्दकोश पर पुनरावृति करने के कई तरीके हैं और कोई सबसे अच्छा तरीका नहीं है। यह जरूरत पर निर्भर करता है और अक्सर स्वाद पर भी।
foreach (var kvp in items)
{
// key is kvp.Key
doStuff(kvp.Value)
}
यदि आपको केवल मूल्य की आवश्यकता है (इसे कॉल करने की अनुमति देता है item
, तो इससे अधिक पठनीय kvp.Value
)।
foreach (var item in items.Values)
{
doStuff(item)
}
आम तौर पर, शुरुआती एक शब्दकोश की गणना के आदेश के बारे में आश्चर्यचकित होते हैं।
LINQ एक संक्षिप्त सिंटैक्स प्रदान करता है जो ऑर्डर (और कई अन्य चीजों) को निर्दिष्ट करने की अनुमति देता है, जैसे:
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
// key is kvp.Key
doStuff(kvp.Value)
}
फिर आपको केवल मूल्य की आवश्यकता हो सकती है। LINQ भी एक संक्षिप्त समाधान प्रदान करता है:
item
, की तुलना में अधिक पठनीय हैkvp.Value
)यह रहा:
foreach (var item in items.OrderBy(kvp => kvp.Key).Select(kvp => kvp.Value))
{
doStuff(item)
}
कई और वास्तविक दुनिया के उपयोग के मामले हैं जो आप इन उदाहरणों से कर सकते हैं। यदि आपको एक विशिष्ट आदेश की आवश्यकता नहीं है, तो बस "सबसे सीधा रास्ता" (ऊपर देखें) से चिपके रहें!
.Values
और एक चयनित खंड नहीं होना चाहिए ।
Value
क्षेत्र नहीं है । सटीक प्रकार मैं यहाँ देख रहा हूँ IOrderedEnumerable<KeyValuePair<TKey, TValue>>
। शायद आपका मतलब कुछ और था? क्या आप एक पूरी लाइन लिख सकते हैं, जिसका अर्थ है कि आप क्या मतलब है (और इसका परीक्षण करें)?
items.Value
जैसा सुझाव दिया वैसा ही लिखा । चौथे खंड के मामले में, जो आपने टिप्पणी की थी, कुंजी-मूल्य जोड़े के बजाय शब्दकोश में मूल्यों पर सीधे गणना Select()
करने का कारण foreach
है। यदि किसी तरह आप Select()
इस मामले में पसंद नहीं करते हैं, तो आप तीसरे कोड अनुभाग को पसंद कर सकते हैं। चौथे खंड का बिंदु यह दिखाना है कि कोई LINQ के साथ संग्रह को पूर्व-संसाधित कर सकता है।
.Keys.Orderby()
आप कुंजियों की सूची पर पुनरावृति करेंगे। अगर आप की जरूरत है, ठीक है। यदि आपको मूल्यों की आवश्यकता है, तो लूप में आपको मूल्य प्राप्त करने के लिए प्रत्येक कुंजी पर शब्दकोश को क्वेरी करना होगा। कई परिदृश्यों में यह व्यावहारिक अंतर नहीं बनाएगा। उच्च-प्रदर्शन परिदृश्य में, यह होगा। जैसे मैंने उत्तर की शुरुआत में लिखा था: "कई तरीके (...) हैं और कोई सबसे अच्छा तरीका नहीं है। यह जरूरत पर निर्भर करता है और अक्सर स्वाद पर भी निर्भर करता है।"
मैं कहूंगा कि फॉर्च्यूनर मानक तरीका है, हालांकि यह स्पष्ट रूप से इस बात पर निर्भर करता है कि आप क्या खोज रहे हैं
foreach(var kvp in my_dictionary) {
...
}
कि तुम क्या देख रहे हो?
kvp
सामान्यतः KeyValuePair उदाहरणों नाम के लिए प्रयोग किया जाता है जब बार-बार दोहराना शब्दकोशों और संबंधित डेटा संरचनाओं पर: foreach(var kvp in myDictionary){...
।
C # 7.0 ने डिकंस्ट्रक्टर्स को पेश किया और यदि आप .NET कोर 2.0+ एप्लिकेशनका उपयोग कर रहे हैं, तो संरचनाआपके लिएKeyValuePair<>
पहले से ही शामिल हैDeconstruct()
। तो आप कर सकते हैं:
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)))
मैं इस सवाल की सराहना करता हूं कि पहले से ही बहुत सारी प्रतिक्रियाएं हैं, लेकिन मैं थोड़ा शोध में फेंकना चाहता था।
किसी सरणी पर किसी चीज़ से अधिक पुनरावृति के साथ तुलना करने पर किसी शब्द पर उच्चारण करना धीमा हो सकता है। मेरे परीक्षणों में एक सरणी पर एक पुनरावृत्ति 0.015003 सेकंड लिया गया जबकि एक शब्दकोश (तत्वों की समान संख्या के साथ) पर एक पुनरावृत्ति 0.0365073 सेकंड लिया, जो कि 2.4 गुना लंबा है! हालांकि मैंने बहुत बड़े अंतर देखे हैं। तुलना के लिए एक सूची कहीं 0.00215043 सेकंड के बीच में थी।
हालाँकि, यह सेब और संतरे की तुलना करने जैसा है। मेरा कहना है कि शब्दकोशों पर चलना धीमा है।
शब्दकोशों को लुकअप के लिए ऑप्टिमाइज़ किया गया है, इसलिए इस बात को ध्यान में रखते हुए कि मैंने दो तरीके बनाए हैं। एक बस एक फॉर्च्यूनर करता है, दूसरा फिर कुंजियों को दिखाता है।
public static string Normal(Dictionary<string, string> dictionary)
{
string value;
int count = 0;
foreach (var kvp in dictionary)
{
value = kvp.Value;
count++;
}
return "Normal";
}
यह एक कुंजी को लोड करता है और इसके बजाय उन पर पुनरावृत्ति करता है (मैंने कुंजियों को एक स्ट्रिंग में खींचने की कोशिश भी की थी] लेकिन अंतर नगण्य था।
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";
}
इस उदाहरण के साथ सामान्य फॉर्च्यूस परीक्षण ने 0.0310062 लिया और कुंजी संस्करण ने 0.2205441 लिया। सभी कुंजियों को लोड करना और सभी लुकअप पर ध्यान देना स्पष्ट रूप से बहुत धीमा है!
एक अंतिम परीक्षण के लिए मैंने दस बार अपनी पुनरावृत्ति का प्रदर्शन किया है, यह देखने के लिए कि क्या यहाँ कुंजियों का उपयोग करने के लिए कोई लाभ हैं (इस बिंदु से मैं अभी उत्सुक था):
यहाँ RunTest तरीका है जो आपको यह कल्पना करने में मदद करता है कि क्या चल रहा है।
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);
}
यहाँ सामान्य फ़ॉरेस्ट रन 0.2820564 सेकंड (लगभग दस गुना अधिक एक एकल पुनरावृत्ति से लिया - जैसा कि आप उम्मीद करेंगे) लिया। कुंजियों पर पुनरावृत्ति ने 2.2249449 सेकंड का समय लिया।
संपादित करने के लिए संपादित करें: कुछ अन्य उत्तरों को पढ़ने से मुझे यह प्रश्न हुआ कि यदि मैं शब्दकोश के बजाय शब्दकोश का उपयोग करता हूं तो क्या होगा। इस उदाहरण में सरणी 0.0120024 सेकंड, सूची 0.0185037 सेकंड और शब्दकोश 0.0465093 सेकंड लिया गया। यह अपेक्षा करना उचित है कि डेटा प्रकार इस बात पर फर्क करता है कि शब्दकोश कितना धीमा है।
मेरे निष्कर्ष क्या हैं ?
बहुत सारे विकल्प हैं। मेरा व्यक्तिगत पसंदीदा KeyValuePair द्वारा है
Dictionary<string, object> myDictionary = new Dictionary<string, object>();
// Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary)
{
// Do some interesting things
}
आप कुंजी और मान संग्रह का उपयोग भी कर सकते हैं
साथ .NET Framework 4.7
उपयोग कर सकते हैं अपघटन
var fruits = new Dictionary<string, int>();
...
foreach (var (fruit, number) in fruits)
{
Console.WriteLine(fruit + ": " + number);
}
इस कोड को निचले C # संस्करणों पर काम करने के लिए, System.ValueTuple NuGet package
कहीं और जोड़ें और लिखें
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
बनाया गया है। यह पुराने संस्करणों के लिए एक नगेट पैकेज के रूप में उपलब्ध है। इससे भी महत्वपूर्ण बात, Deconstruct
विधि के लिए C # 7.0+ की आवश्यकता है, जिसके लिए एक डिकंस्ट्रक्टर के रूप में काम करना है var (fruit, number) in fruits
।
C # 7 के अनुसार, आप ऑब्जेक्ट्स को वेरिएबल्स में डिक्रिप्ट कर सकते हैं। मेरा मानना है कि यह एक शब्दकोश पर पुनरावृति करने का सबसे अच्छा तरीका है।
उदाहरण:
KeyValuePair<TKey, TVal>
उस पर डिकॉन्स्ट्रक्ट करता है एक विस्तार विधि बनाएँ :
public static void Deconstruct<TKey, TVal>(this KeyValuePair<TKey, TVal> pair, out TKey key, out TVal value)
{
key = pair.Key;
value = pair.Value;
}
Dictionary<TKey, TVal>
निम्नलिखित तरीके से किसी पर भी फेरबदल करें
// 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}");
}
आपने इसे पुनरावृति का सुझाव दिया है
Dictionary<string,object> myDictionary = new Dictionary<string,object>();
//Populate your dictionary here
foreach (KeyValuePair<string,object> kvp in myDictionary) {
//Do some interesting things;
}
foreach
अगर मूल्य प्रकार की वस्तु के हैं , तो FYI, काम नहीं करता है।
foreach
काम नहीं करेगा यदि मूल्य किस प्रकार का है object
? अन्यथा यह बहुत मतलब नहीं है।
C # 7 का उपयोग करते हुए , अपने समाधान की किसी भी परियोजना में इस विस्तार विधि को जोड़ें :
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);
}
}
और इस सरल वाक्यविन्यास का उपयोग करें
foreach (var(id, value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
या यह एक, यदि आप पसंद करते हैं
foreach ((string id, object value) in dict.Tuples())
{
// your code using 'id' and 'value'
}
पारंपरिक के स्थान पर
foreach (KeyValuePair<string, object> kvp in dict)
{
string id = kvp.Key;
object value = kvp.Value;
// your code using 'id' and 'value'
}
विस्तार विधि KeyValuePair
आपके IDictionary<TKey, TValue>
एक मजबूत टाइप में तब्दील हो जाती है tuple
, जिससे आप इस नए आरामदायक वाक्यविन्यास का उपयोग कर सकते हैं।
यह धर्मान्तरित-अन्याय करता है - आवश्यक शब्दकोश प्रविष्टियों को tuples
, इसलिए यह पूरे शब्दकोश को धर्मान्तरित नहीं करता है, इसलिए इससे tuples
संबंधित प्रदर्शन चिंताएं नहीं हैं।
सीधे tuple
उपयोग करने की तुलना में ए बनाने के लिए एक्सटेंशन मेथड को कॉल करने के लिए केवल एक मामूली लागत है KeyValuePair
, जो एक मुद्दा नहीं होना चाहिए यदि आप किसी भी तरह के नए KeyValuePair
गुणों Key
और Value
नए लूप चर को असाइन कर रहे हैं ।
व्यवहार में, यह नया वाक्य-विन्यास अधिकांश मामलों के लिए बहुत उपयुक्त है, निम्न-स्तरीय अल्ट्रा-उच्च प्रदर्शन परिदृश्यों को छोड़कर, जहां आपके पास अभी भी उस विशिष्ट स्थान पर इसका उपयोग नहीं करने का विकल्प है।
इसे देखें: MSDN ब्लॉग - C # 7 में नई सुविधाएँ
kvp.Key
और kvp.Value
क्रमशः कुंजी और मूल्य का उपयोग करना चाहिए । ट्यूपल्स के साथ आपको फ़ॉरच ब्लॉक के अंदर और परिवर्तनशील घोषणाओं का उपयोग किए बिना, कुंजी और मान को नाम देने की सुविधा मिलती है। उदाहरण के लिए, आप अपनी कुंजी को नाम दे सकते हैं factoryName
और मान models
, जो कि विशेष रूप से उपयोगी है जब आपको नेस्टेड लूप (शब्दकोशों के शब्दकोश) मिलते हैं: कोड रखरखाव बहुत आसान हो जाता है। इसे मात्र आजमाएं! ;-)
मुझे पता है कि यह एक बहुत पुराना प्रश्न है, लेकिन मैंने कुछ विस्तार विधियाँ बनाई हैं जो उपयोगी हो सकती हैं:
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); }
}
इस तरह मैं इस तरह कोड लिख सकता हूं:
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););
कभी-कभी यदि आपको केवल मूल्यों की गणना करने की आवश्यकता है, तो शब्दकोश के मूल्य संग्रह का उपयोग करें:
foreach(var value in dictionary.Values)
{
// do something with entry.Value only
}
इस पोस्ट द्वारा रिपोर्ट की गई, जिसमें लिखा गया है कि यह सबसे तेज़ तरीका है: http://alexpinsker.blogspot.hk/2010/02/c-fastest-way-to-iterate-over.html
मैंने MSDN पर DictionaryBase वर्ग के लिए प्रलेखन में यह तरीका पाया:
foreach (DictionaryEntry de in myDictionary)
{
//Do some stuff with de.Value or de.Key
}
यह एकमात्र ऐसा वर्ग था, जो डिक्शनबेस से विरासत में मिली कक्षा में सही ढंग से काम करने में सक्षम था।
Hashtable
वस्तुओं के लिए उपयोग किया जाने वाला गैर-जेनेरिक संस्करण है
ContainsKey()
में क्यों बुला रहे हैं for
? अतिरिक्त ओवरहेड जोड़ता है जो आपके द्वारा तुलना किए जा रहे कोड में मौजूद नहीं है। TryGetValue()
उस सटीक को बदलने के लिए मौजूद है "यदि कुंजी मौजूद है, तो कुंजी को" पैटर्न के साथ प्राप्त करें। इसके अलावा, अगर dict
से पूर्णांकों का एक सन्निहित रेंज शामिल 0
करने के लिए dictCount - 1
, तुम्हें पता है इंडेक्सर असफल नहीं हो सकता; अन्यथा, dict.Keys
आपको जो पुनरावृत्त होना चाहिए। किसी भी तरह से, कोई ContainsKey()
/ TryGetValue()
जरूरत है। अंतिम, कृपया कोड के स्क्रीनशॉट पोस्ट न करें।
मैंने एक शब्दकोश में लूप का विस्तार लिखा।
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);
}
}
}
तब आप कॉल कर सकते हैं
myDictionary.ForEach((x,y) => Console.WriteLine(x + " - " + y));
ForEach
विधि को परिभाषित किया है जिसमें आपके पास foreach (...) { }
... अनावश्यक जैसा लगता है।
यदि कहें, तो आप डिफ़ॉल्ट रूप से मान संग्रह पर चलना चाहते हैं, मेरा मानना है कि आप IEnumerable <> को लागू कर सकते हैं, जहां टी शब्दकोश में मान ऑब्जेक्ट का प्रकार है, और "यह" एक शब्दकोश है।
public new IEnumerator<T> GetEnumerator()
{
return this.Values.GetEnumerator();
}
बस मेरा 2 प्रतिशत जोड़ना चाहते थे, क्योंकि अधिकांश उत्तर फॉरच-लूप से संबंधित थे। कृपया, निम्नलिखित कोड पर एक नज़र डालें:
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));
});
यह सोचा गया कि '.TLList ()' का एक अतिरिक्त कॉल आता है, इसमें थोड़ा सा प्रदर्शन-सुधार हो सकता है (जैसा कि यहां बताया गया है। someList.Foreach () {} ), बड़े शब्दों के साथ काम करते समय और समानांतर रूप से चलने पर स्पष्ट रूप से नहीं है विकल्प / का असर बिल्कुल नहीं होगा।
इसके अलावा, कृपया ध्यान दें कि आप फॉरेस्ट लूप के अंदर 'वैल्यू' प्रॉपर्टी को वैल्यू असाइन करने में सक्षम नहीं होंगे। दूसरी ओर, आप 'की' को भी हेरफेर करने में सक्षम होंगे, संभवतः रनटाइम में आपको परेशानी हो सकती है।
जब आप केवल कुंजी और मान "पढ़ना" चाहते हैं, तो आप IEnumerable.Select () का भी उपयोग कर सकते हैं।
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
foreach
साइड-इफ़ेक्ट विजिबिलिटी को बढ़ाता है , जहाँ यह होता है।
var dictionary = new Dictionary<string, int>
{
{ "Key", 12 }
};
var aggregateObjectCollection = dictionary.Select(
entry => new AggregateObject(entry.Key, entry.Value));
AggregateObject
जोड़ता है KeyValuePair
? प्रश्न में अनुरोध के अनुसार "पुनरावृत्ति" कहां है?
foreach
, लेकिन मैंने इसका भरपूर उपयोग किया है। क्या मेरा जवाब सही मायने में नीच है?
Select
लिए पुनरावृत्ति का उपयोग करता है , लेकिन स्वयं एक पुनरावृत्ति नहीं है। चीजों के प्रकार जो कि पुनरावृत्ति ( foreach
) के लिए उपयोग किए जाते हैं - विशेष रूप से साइड-इफेक्ट्स के साथ ऑपरेशन - लाइनक के दायरे से बाहर हैं, जिसमें शामिल हैं Select
। लैम्बडा तब तक नहीं चलेगा जब तक aggregateObjectCollection
कि वास्तव में गणना नहीं हो जाती। यदि इस उत्तर को "पहले पथ" के रूप में लिया जाता है (यानी, सीधे से पहले इस्तेमाल किया जाता है foreach
) यह बुरी प्रथाओं को प्रोत्साहित करता है। स्थिति के अनुसार, Linq ऑपरेशंस हो सकते हैं जो किसी शब्दकोश को पुनरावृत्त करने से पहले मददगार होते हैं , लेकिन यह पूछे गए सवाल को संबोधित नहीं करता है।
शब्दकोश <TKey, TValue> यह c # में एक सामान्य संग्रह वर्ग है और यह डेटा को मुख्य मूल्य प्रारूप में संग्रहीत करता है। इसे अद्वितीय होना चाहिए और यह शून्य नहीं हो सकता है, जबकि मूल्य डुप्लिकेट और शून्य हो सकता है। शब्दकोश में प्रत्येक आइटम। KeyValuePair <TKey, TValue> संरचना के रूप में माना जाता है जो एक कुंजी और उसके मूल्य का प्रतिनिधित्व करता है। और इसलिए हमें तत्व के पुनरावृत्ति के दौरान तत्व प्रकार KeyValuePair <TKey, TValue> लेना चाहिए। नीचे उदाहरण है।
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);
}
यदि आप लूप के लिए उपयोग करना चाहते हैं, तो आप यह कर सकते हैं:
var keyList=new List<string>(dictionary.Keys);
for (int i = 0; i < keyList.Count; i++)
{
var key= keyList[i];
var value = dictionary[key];
}
foreach
लूप और खराब प्रदर्शन की तुलना में अधिक लंबा कोड है क्योंकि इससे पहले कि आप स्वयं इसे पुनरावृत्त करने का मौका new List<string>(dictionary.Keys)
होगा, dictionary.Count
इससे पहले भी इसे पुन: व्यवस्थित करेंगे। यह कहते हुए कि "सबसे अच्छा तरीका" के लिए पूछना व्यक्तिपरक है, मैं यह नहीं देखता कि यह "सबसे अच्छा तरीका" या "मानक तरीके" के रूप में कैसे योग्य होगा जो प्रश्न पूछते हैं। "यदि आप लूप के लिए उपयोग करना चाहते हैं ..." मैं " लूप का उपयोग न करें " के साथ काउंटर करूंगा for
।
foreach (var pair in dictionary.ToArray()) { }
। फिर भी, मुझे लगता है कि विशिष्ट परिदृश्य (नों) के उत्तर में स्पष्ट करना अच्छा होगा, जिसमें कोई इस कोड और ऐसा करने के निहितार्थ का उपयोग करना चाहेगा।
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()
क्योंकि ForEach()
केवल List<>
कक्षा पर परिभाषित किया गया है , लेकिन सिर्फ इसके बजाय सभी क्यों करते हैं foreach (var pair in dict) { }
? मैं कहता हूं कि यह और भी सरल है और इसमें समान मेमोरी / प्रदर्शन निहितार्थ नहीं हैं। यह सटीक समाधान पहले से ही इस उत्तर में 3.5 साल पहले से प्रस्तावित था, वैसे भी।
उच्चतम रैंकिंग पदों के अलावा जहां उपयोग करने के बीच एक चर्चा है
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
या
foreach(var entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
सबसे पूर्ण निम्नलिखित है क्योंकि आप आरंभिक से शब्दकोश प्रकार देख सकते हैं, kvp 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
}