C # හි ශබ්දකෝෂයක් හරහා නැවත යෙදීමට විවිධ ක්රම කිහිපයක් මම දැක ඇත්තෙමි. සම්මත ක්රමයක් තිබේද?
C # හි ශබ්දකෝෂයක් හරහා නැවත යෙදීමට විවිධ ක්රම කිහිපයක් මම දැක ඇත්තෙමි. සම්මත ක්රමයක් තිබේද?
Answers:
foreach(KeyValuePair<string, string> entry in myDictionary)
{
// do something with entry.Value or entry.Key
}
var entry
එම අවස්ථාවේ දී භාවිතා කිරීම වඩා හොඳය, එබැවින් මම ඉහත පිළිතුර වෙනුවට දෙවන පෙනුමෙන් මෙම පිළිතුර ඡන්දය ප්රකාශ කළෙමි .
var
වර්ගය සාමාන්යයෙන් නරක පුරුද්දක් බව ඔබ නොදන්නා විට භාවිතා කිරීම.
var
ක්රියා කරන්නේ වර්ගය සම්පාදනය කරන වේලාවේදී නම් පමණි. විෂුවල් ස්ටුඩියෝ වර්ගය දන්නේ නම් එය ඔබට ද සොයා ගත හැකිය.
ඔබ 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
(එය ඇත්ත වශයෙන්ම පා name මාලාවේ නම නොවේ නම්). වර්ගය පැහැදිලිව පෙනෙන විට var භාවිතා කිරීම හොඳ යැයි මම සිතමි. var x = "some string"
නමුත් එය ක්ෂණිකව නොපෙනෙන විට එය කේත කියවන්නාට / විචාරකයාට රිදවන කම්මැලි කේතීකරණයක් යැයි මම සිතමි
var
මගේ මතය අනුව අරපිරිමැස්මෙන් භාවිතා කළ යුතුය. විශේෂයෙන් මෙහි, එය ruc ලදායී නොවේ: වර්ගය 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
එය සාමාන්ය (n) මෙහෙයුම?
.ElementAt
මෙම සන්දර්භය තුළ භාවිතා කිරීම සියුම් දෝෂ වලට තුඩු දිය හැකිය. ආටුරෝගේ කාරණය ඊටත් වඩා බරපතල ය. dictionary.Count + 1
O (n) පමණක් විය යුතු මෙහෙයුමක් සඳහා O (n ^ 2) සංකීර්ණතාවයට තුඩු දෙන ශබ්ද කෝෂ වේලාවන් ඔබ නැවත කියනු ඇත . ඔබට සැබවින්ම දර්ශකයක් අවශ්ය නම් (ඔබ එසේ කරන්නේ නම්, ඔබ බොහෝ විට වැරදි එකතු කිරීමේ වර්ගය මුලින් භාවිතා කරයි), ඔබ 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)
}
සාමාන්යයෙන්, ශබ්ද කෝෂයක් ගණනය කිරීමේ අනුපිළිවෙල ගැන ආරම්භකයින් පුදුම වේ.
ඇණවුම (සහ තවත් බොහෝ දේ) නියම කිරීමට ඉඩ දෙන සංක්ෂිප්ත වාක්ය ඛණ්ඩයක් ලින්ක් සපයයි, උදා:
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()
යතුරු ලැයිස්තුවක් මත නැවත කියනු ඇත. ඔබට අවශ්ය වන්නේ එපමණක් නම් හොඳයි. ඔබට අගයන් අවශ්ය නම්, ලූපය තුළ අගය ලබා ගැනීම සඳහා එක් එක් යතුරේ ශබ්ද කෝෂය විමසීමට සිදුවේ. බොහෝ අවස්ථාවන්හි එය ප්රායෝගික වෙනසක් නොකරනු ඇත. ඉහළ කාර්යසාධනයක් සහිත අවස්ථාවක, එය එසේ වනු ඇත. පිළිතුර ආරම්භයේ මා ලියා ඇති පරිදි: "බොහෝ ක්රම තිබේ (...) සහ හොඳම ක්රමයක් නොමැත. එය අවශ්යතාවය මත රඳා පවතින අතර බොහෝ විට රසය මත ද වේ."
මම කියන්නේ foreach යනු සම්මත ක්රමය බවයි, නමුත් එය පැහැදිලිවම ඔබ සොයන දේ මත රඳා පවතී
foreach(var kvp in my_dictionary) {
...
}
ඔබ සොයන්නේ එයද?
kvp
බහුලව භාවිතා වන්නේ ශබ්ද කෝෂ සහ අදාළ දත්ත ව්යුහයන් හරහා යතුරු ලියනය කිරීමේදී KeyValuePair අවස්ථා නම් කිරීමට ය : foreach(var kvp in myDictionary){...
.
C # 7.0 විසින් Deconstructors හඳුන්වා දී ඇති අතර ඔබ .NET Core 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)))
බහු තෙරපුම් සැකසුම් සඳහා ඔබට විශාල ශබ්ද කෝෂවල මෙය උත්සාහ කළ හැකිය.
dictionary
.AsParallel()
.ForAll(pair =>
{
// Process pair.Key and pair.Value here
});
මෙම ප්රශ්නයට දැනටමත් විශාල ප්රතිචාර ප්රමාණයක් ලැබී ඇති බව මම අගය කරමි, නමුත් මට කුඩා පර්යේෂණයක් කිරීමට අවශ්ය විය.
අරාව වැනි දෙයක් හරහා නැවත යෙදීම සමඟ සසඳන විට ශබ්ද කෝෂයක් හරහා යෙදීම තරමක් මන්දගාමී විය හැකිය. මගේ පරීක්ෂණ වලදී අරාවකට වඩා පුනරාවර්තනයක් තත්පර 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";
}
මෙම උදාහරණය සමඟ සාමාන්ය foreach පරීක්ෂණය 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);
}
මෙහි සාමාන්ය foreach ධාවනය සඳහා තත්පර 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
ගොඩනගා ඇත. එය පෙර සංස්කරණ සඳහා නූගට් පැකේජයක් ලෙස ලබා ගත හැකිය. වැදගත්ම දෙය නම්, C # 7.0+ Deconstruct
ක්රමය සඳහා විසංයෝජකයෙකු ලෙස වැඩ කිරීමට අවශ්ය වේ 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;
}
FYI, foreach
අගය වර්ගයේ වස්තුවක් නම් ක්රියා නොකරයි.
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'
}
දීර් extension කිරීමේ ක්රමය 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 හි ශබ්ද කෝෂ පංතිය සඳහා වන ප්රලේඛනය තුළ මෙම ක්රමය මට හමු විය:
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 <> ක්රියාත්මක කළ හැකි යැයි මම විශ්වාස කරමි, එහිදී T යනු ශබ්ද කෝෂයේ ඇති වටිනාකම් වස්තුවේ වර්ගය වන අතර “මෙය” ශබ්දකෝෂයකි.
public new IEnumerator<T> GetEnumerator()
{
return this.Values.GetEnumerator();
}
මෙම පිළිතුරෙහි දැනටමත් පෙන්වා දී ඇති පරිදි , KeyValuePair<TKey, TValue>
aDeconstruct
.NET Core 2.0, .NET සම්මත 2.1 හා .NET Framework 5.0 (පෙරදසුනෙහි) වන දින ආරම්භ ක්රමය.
මේ සමඟ, අ KeyValuePair
nost ෙයවාදී ආකාරයකින් ශබ්ද කෝෂයක් හරහා නැවත කියවිය හැකිය :
var dictionary = new Dictionary<int, string>();
// ...
foreach (var (key, value) in dictionary)
{
// ...
}
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
) එය නරක පුරුදු දිරිගන්වයි. කාලානුරූපව , ශබ්ද කෝෂයක් නැවත යෙදීමට පෙර ලින්ක් මෙහෙයුම් ප්රයෝජනවත් විය හැකි නමුත් එය ඇසූ පරිදි ප්රශ්නයට ආමන්ත්රණය නොකරයි.
මගේ ශත 2 එකතු කිරීමට අවශ්ය වූ නිසා, බොහෝ පිළිතුරු foreach-loop හා සම්බන්ධ වේ. කරුණාකර, පහත කේතය දෙස බලන්න:
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 ()' හි අතිරේක ඇමතුමක් එක් කරයි, සුළු කාර්ය සාධනයක්-වැඩිදියුණු කිරීමක් තිබිය හැකිය (මෙහි පෙන්වා ඇති පරිදි someList.Foreach () vs} ), espacially විශාල ශබ්ද කෝෂ සමඟ වැඩ කරන හා සමගාමීව ක්රියාත්මක වන විටදී නැත විකල්පය / කිසිසේත්ම බලපෑමක් ඇති නොකරනු ඇත.
තවද, පුරෝකථන ලූපයක් තුළ ඇති 'අගය' දේපල සඳහා අගයන් පැවරීමට ඔබට නොහැකි බව කරුණාවෙන් සලකන්න. අනෙක් අතට, ඔබට 'යතුර' හැසිරවීමට හැකි වනු ඇත, සමහර විට ධාවන වේලාවේදී ඔබව කරදරයට පත් කරනු ඇත.
ඔබට යතුරු සහ අගයන් "කියවීමට" අවශ්ය වූ විට, ඔබට IEnumerable භාවිතා කළ හැකිය. තෝරන්න ().
var newProductPrices = myProductPrices.Select(kvp => new { Name = kvp.Key, Price = kvp.Value * 1.15 } );
foreach
අතුරු ආබාධ දෘශ්යතාව එය අයිති තැනට බල කරයි.
ශබ්දකෝෂය <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()) { }
හැකිය. කෙසේ වෙතත්, මෙම කේතය භාවිතා කිරීමට යමෙකුට අවශ්ය වන නිශ්චිත අවස්ථා (ය) සහ එසේ කිරීමේ ඇඟවුම් පිළිතුරෙන් පැහැදිලි කිරීම හොඳ යැයි මම සිතමි.
ලින්ක් සමඟ සරලයි
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()
නිසා බව මට පෙනේ , නමුත් සාධාරණ වෙනුවට ඒ සියල්ල කරන්නේ ඇයි ? මම කියන්නේ එය ඊටත් වඩා සරල වන අතර එකම මතකයක් / කාර්ය සාධනයක් නොමැති බවයි. මෙම පිළිතුරෙහි මීට වසර 3.5 කට පෙර සිට කෙසේ හෝ මෙම නිශ්චිත විසඳුම දැනටමත් යෝජනා කර ඇත . ForEach()
List<>
foreach (var pair in dict) { }
භාවිතා කිරීම අතර සාකච්ඡාවක් පවතින ඉහළම තනතුරු වලට අමතරව
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
}