আমি সি # তে একটি অভিধানে পুনরাবৃত্তি করার কয়েকটি ভিন্ন উপায় দেখেছি। মানক উপায় আছে কি?
আমি সি # তে একটি অভিধানে পুনরাবৃত্তি করার কয়েকটি ভিন্ন উপায় দেখেছি। মানক উপায় আছে কি?
উত্তর:
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
var entry
করা আরও ভাল, এবং এইভাবে আমি এই উত্তরটিকে উপরেরটির পরিবর্তে দ্বিতীয় বর্ণে ভোট দিয়েছি।
var
আপনি যখন টাইপটি জানেন না তখন @ ওজিরকাফ্রে ব্যবহার করা সাধারণত খারাপ অভ্যাস।
var
কেবল তখনই কাজ করে যদি টাইপটি সংকলন করার সময় জানা যায়। যদি ভিজ্যুয়াল স্টুডিওটি প্রকারটি জানে তবে আপনার পক্ষে এটি সন্ধানের জন্য এটি উপলব্ধ।
আপনি যদি সি # তে জেনেরিক অভিধান ব্যবহার করার চেষ্টা করছেন তবে আপনি অন্য ভাষায় কোনও এসোসিয়েটিভ অ্যারে ব্যবহার করবেন:
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
একটি অনন্য উদ্দেশ্য আছে এবং আমি বিশ্বাস করি না এটি 'সিনট্যাকটিক' চিনি। উদ্দেশ্যমূলকভাবে এটি ব্যবহার করা একটি উপযুক্ত পদ্ধতি।
কিছু ক্ষেত্রে আপনার একটি কাউন্টারের প্রয়োজন হতে পারে যা লুপ বাস্তবায়নের মাধ্যমে সরবরাহ করা যেতে পারে। তার জন্য, লিনকিউ সরবরাহ করে ElementAt
যা নিম্নলিখিতগুলিকে সক্ষম করে:
for (int index = 0; index < dictionary.Count; index++) {
var item = dictionary.ElementAt(index);
var itemKey = item.Key;
var itemValue = item.Value;
}
ElementAt
একটি হে (ঢ) অপারেশন?
.ElementAt
এই প্রসঙ্গে ব্যবহারের ফলে সূক্ষ্ম বাগগুলি হতে পারে। আর্টুরোর বিষয়টি আরও গুরুতর। আপনি অভিধানের পুনরাবৃত্তি করতে যাবেন dictionary.Count + 1
ও (n ^ 2) এমন কোনও ক্রিয়াকলাপের জন্য যা কেবল ও (এন) হওয়া উচিত for আপনার যদি সত্যিই একটি সূচক প্রয়োজন হয় (যদি আপনি এটি করেন তবে সম্ভবত আপনি প্রথম স্থানে ভুল সংগ্রহের ধরণটি ব্যবহার করছেন), আপনার dictionary.Select( (kvp, idx) => new {Index = idx, kvp.Key, kvp.Value})
পরিবর্তে পুনরাবৃত্তি করা উচিত এবং .ElementAt
লুপের অভ্যন্তরে ব্যবহার করা উচিত নয় ।
আপনি কীগুলি বা মানগুলি পরে যাচ্ছেন তার উপর নির্ভর করে ...
এমএসডিএন 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);
}
সাধারণত, নির্দিষ্ট প্রসঙ্গ ব্যতীত "সেরা উপায়ে" জিজ্ঞাসা করা সর্বোত্তম রঙটি কী তা জিজ্ঞাসার মতো ?
একদিকে, অনেকগুলি রঙ রয়েছে এবং সর্বোত্তম রঙ নেই। এটি প্রয়োজন এবং প্রায়শই স্বাদেও নির্ভর করে।
অন্যদিকে, সি # তে একটি অভিধানে পুনরাবৃত্তি করার অনেকগুলি উপায় রয়েছে এবং এর সর্বোত্তম উপায় নেই। এটি প্রয়োজন এবং প্রায়শই স্বাদেও নির্ভর করে।
foreach (var kvp in items)
{
// key is kvp.Key
doStuff(kvp.Value)
}
আপনার যদি কেবলমাত্র মান প্রয়োজন হয় (এটিকে কল করতে দেয় item
, এর চেয়ে বেশি পাঠযোগ্য kvp.Value
)।
foreach (var item in items.Values)
{
doStuff(item)
}
সাধারণত, অভিধানগুলি অঙ্কের ক্রম সম্পর্কে বিস্মিত হয় অবাক হন।
লিনিক্যু একটি সংক্ষিপ্ত বাক্য গঠন সরবরাহ করে যা অর্ডার (এবং আরও অনেকগুলি জিনিস) নির্দিষ্ট করতে দেয়, যেমন:
foreach (var kvp in items.OrderBy(kvp => kvp.Key))
{
// key is kvp.Key
doStuff(kvp.Value)
}
আবার আপনার কেবল মূল্য প্রয়োজন হতে পারে। লিনকিউ একটি সংক্ষিপ্ত সমাধানও সরবরাহ করে:
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()
কীগুলির তালিকায় পুনরাবৃত্তি করতে পারেন । আপনার যদি এটির দরকার হয় তবে ঠিক আছে। আপনার যদি মানগুলির প্রয়োজন হয় তবে লুপে আপনাকে মানটি পেতে প্রতিটি কীতে অভিধানটি জিজ্ঞাসা করতে হবে। অনেক পরিস্থিতিতে এটি ব্যবহারিক পার্থক্য করে না। উচ্চ-পারফরম্যান্সের দৃশ্যে এটি হবে। যেমন আমি উত্তরের শুরুতে লিখেছিলাম: "অনেক উপায় আছে (...) এবং এর থেকে সেরা উপায় নেই It এটি প্রয়োজন এবং প্রায়শই স্বাদের উপরও নির্ভর করে।"
আমি বলব foreach হ'ল মানক উপায়, যদিও এটি আপনি যা খুঁজছেন তার উপর স্পষ্টভাবে নির্ভর করে
foreach(var kvp in my_dictionary) {
...
}
আপনি কি এটি খুঁজছেন?
kvp
সাধারণভাবে KeyValuePair দৃষ্টান্ত নাম ব্যবহার করা হয় যখন iterating অভিধান এবং সংশ্লিষ্ট ডাটা স্ট্রাকচার ওপরে foreach(var kvp in myDictionary){...
।
সি # 7.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 নিয়েছে। সমস্ত কীগুলি লোড করা এবং সমস্ত লুক্কুলের উপরে পুনরাবৃত্তি করা স্পষ্টতই অনেক ধীর গতির!
চূড়ান্ত পরীক্ষার জন্য আমি দশবার আমার পুনরাবৃত্তিটি সম্পাদন করেছি এখানে কীগুলি ব্যবহার করার কোনও সুবিধা রয়েছে কিনা তা দেখার জন্য (এই মুহুর্তে আমি কেবল কৌতূহলী ছিলাম):
এখানে রানটেষ্ট পদ্ধতিটি যদি এটি আপনাকে কী ঘটছে তা কল্পনা করতে সহায়তা করে।
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 সেকেন্ড নিয়েছিল। এটি আশা করা যুক্তিসঙ্গত যে ডেটা টাইপটি অভিধানটি কত ধীরে ধীরে ধীরে ধীরে তা কমিয়ে দেয়।
আমার সিদ্ধান্তগুলি কী কী ?
বিকল্প প্রচুর আছে। আমার ব্যক্তিগত প্রিয়টি কিভ্যালিউপায়ার
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);
}
এই কোডটি নিম্ন সি # সংস্করণে কাজ করতে, 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
অন্তর্নির্মিত হয়েছে earlier এটি পূর্ববর্তী সংস্করণগুলির জন্য ন্যুগেট প্যাকেজ হিসাবে উপলব্ধ। আরও গুরুত্বপূর্ণ বিষয় হল, Deconstruct
পদ্ধতিটির জন্য ডিকনস্ট্রাক্টর হিসাবে কাজ করার জন্য সি # 7.0+ প্রয়োজন var (fruit, number) in fruits
।
সি # 7 হিসাবে, আপনি ভেরিয়েবলগুলিতে অবজেক্টগুলি ডিকনস্ট্রাক্ট করতে পারেন। আমি বিশ্বাস করি এটি কোনও অভিধানে পুনরাবৃত্তি করার সেরা উপায় be
উদাহরণ:
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
মান টাইপ অবজেক্টের হলে কাজ করে না।
foreach
হলে কাজ করবে না ? অন্যথায় এটি খুব একটা বোঝায় না। object
সি # 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
নতুন লুপ ভেরিয়েবল যাহাই হউক না কেন।
অনুশীলনে, এই নতুন সিনট্যাক্সটি নিম্ন-স্তরের অতি-উচ্চতর পারফরম্যান্সের পরিস্থিতি বাদ দিয়ে বেশিরভাগ ক্ষেত্রেই খুব ভাল মানায়, যেখানে এখনও আপনার কাছে সেই নির্দিষ্ট জায়গায় এটি ব্যবহার না করার বিকল্প রয়েছে।
এটি দেখুন: এমএসডিএন ব্লগ - সি # 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
এমএসডিএন-তে অভিধানবাস বেসের জন্য নথিতে এই পদ্ধতিটি পেয়েছি:
foreach (DictionaryEntry de in myDictionary)
{
//Do some stuff with de.Value or de.Key
}
অভিধানবাজে থেকে উত্তরাধিকার সূত্রে প্রাপ্ত ক্লাসে এই আমিই একমাত্র সঠিকভাবে কাজ করতে সক্ষম হয়েছি।
Hashtable
বস্তুগুলির জন্য ব্যবহৃত জেনারিক সংস্করণ
ContainsKey()
মধ্যে for
সংস্করণ? এটি অতিরিক্ত ওভারহেড যুক্ত করে যা আপনার সাথে তুলনা করছেন কোডটিতে নেই। TryGetValue()
সঠিকটি প্রতিস্থাপন করতে উপস্থিত রয়েছে "যদি কী উপস্থিত থাকে তবে কী দিয়ে আইটেমটি পান" প্যাটার্ন। উপরন্তু, যদি dict
থেকে পূর্ণসংখ্যার একটি সংলগ্ন পরিসীমা রয়েছে 0
করার dictCount - 1
, আপনি কি জানেন indexer ব্যর্থ হতে পারে না; অন্যথায়, 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 <> প্রয়োগ করতে পারবেন, যেখানে টি অভিধানে মানের মানগুলির ধরণ এবং "এটি" একটি অভিধান is
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));
});
ভেবেছিলাম এটি '.ToList ()' এর একটি অতিরিক্ত কল যোগ করে, এখানে সামান্য পারফরম্যান্স-উন্নতি হতে পারে (যেমন এখানে পূর্বাপর বনাম কিছু লিস্ট.ফোর্যাচ () {} ) উল্লেখ করা হয়েছে, বিশেষত বৃহত্তর ডিকোরিয়ানের সাথে কাজ করার সময় এবং সমান্তরালে চলমান কোনও নয় বিকল্প / এর কোনও প্রভাব নেই।
এছাড়াও, দয়া করে নোট করুন যে আপনি কোনও ফোরচ-লুপের অভ্যন্তরে 'মান' সম্পত্তিতে মানগুলি নির্ধারণ করতে সক্ষম হবেন না। অন্যদিকে, আপনি সম্ভবত 'কী' চালিত করতে সক্ষম হবেন, সম্ভবত রানটাইমে আপনাকে সমস্যায় ফেলবেন।
আপনি যখন কী এবং মানগুলি কেবল "পড়তে" চান, আপনি আইনিউমারেবলও ব্যবহার করতে পারেন e নির্বাচন করুন ()।
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
আসলে গণনা করা চলবে না actually যদি এই উত্তরটিকে "প্রথম পথ" হিসাবে গ্রহণ করা হয় (অর্থাত্ সরল আগে ব্যবহৃত foreach
) এটি খারাপ অভ্যাসকে উত্সাহ দেয়। পরিস্থিতিগতভাবে, লিনক অপারেশনগুলি হতে পারে যা কোনও অভিধান পুনরাবৃত্তি করার আগে সহায়ক , তবে এটি যেভাবে প্রশ্ন করা হয়েছে তেমন সমাধান করে না।
অভিধান <টি কে, টিভিলিউ> এটি সি # তে জেনেরিক সংগ্রহের শ্রেণি এবং এটি মূল মান বিন্যাসে ডেটা সংরক্ষণ করে ey কে অবশ্যই অনন্য হতে হবে এবং এটি নাল হতে পারে না যেখানে মানটি নকল এবং নাল হতে পারে the অভিধানে প্রতিটি আইটেম হিসাবে কীভ্যালিউ পেয়ার <টিকি, টিভিয়াল> কাঠামো এবং এর মানকে উপস্থাপন করে এমন কাঠামো হিসাবে বিবেচিত। এবং সেইজন্য উপাদানটির পুনরাবৃত্তির সময় আমাদের কীভ্যালিউয়ার পেয়ার <টি কে, টিভিয়াল>> টাইপ করা উচিত। নীচে উদাহরণ দেওয়া আছে।
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()) { }
। তবুও, আমি মনে করি যে উত্তরে নির্দিষ্ট পরিস্থিতি (গুলি) যে কোনওটিতে এই কোডটি ব্যবহার করতে চাইবে এবং এর ফলে কী হবে তা পরিষ্কার করে দেওয়া ভাল।
লিনাক দিয়ে সহজ
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
}
সর্বাধিক সম্পূর্ণ নিম্নলিখিতটি কারণ আপনি সূচনা থেকে অভিধানের ধরণটি দেখতে পারেন, কেভিপি হ'ল কীভ্যালিউপায়ার
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
}