更改字典关键字的最佳方式
本文关键字:最佳 方式 关键字 字典 | 更新日期: 2023-09-27 18:00:36
我想知道有没有更好的方法来更改字典键,例如:
var dic = new Dictionary<string, int>();
dic.Add("a", 1);
后来我决定将键值对设为("b",1),是否可以只重命名键,而不是添加一个新的键值对("b",1)然后删除"b";a"?
不,一旦添加到字典中,就不能重命名键。如果你想要一个重命名工具,也许可以添加你自己的扩展方法:
public static void RenameKey<TKey, TValue>(this IDictionary<TKey, TValue> dic,
TKey fromKey, TKey toKey)
{
TValue value = dic[fromKey];
dic.Remove(fromKey);
dic[toKey] = value;
}
c#中的Dictionary
被实现为哈希表。因此,如果您能够通过某种Dictionary.ChangeKey
方法更改密钥,则必须对条目进行重新散列。因此,这与删除条目,然后用新密钥再次添加条目没有什么不同(除了方便之外)。
public static bool ChangeKey<TKey, TValue>(this IDictionary<TKey, TValue> dict,
TKey oldKey, TKey newKey)
{
TValue value;
if (!dict.TryGetValue(oldKey, out value))
return false;
dict.Remove(oldKey);
dict[newKey] = value; // or dict.Add(newKey, value) depending on ur comfort
return true;
}
与Colin的回答相同,但没有抛出异常,而是在失败时返回false
。事实上,考虑到编辑键值是危险的,我认为字典类中应该默认这样的方法,所以类本身应该给我们一个安全的选项。
从开始。NET核心,这更有效:
public static bool ChangeKey<TKey, TValue>(this IDictionary<TKey, TValue> dict,
TKey oldKey, TKey newKey)
{
TValue value;
if (!dict.Remove(oldKey, out value))
return false;
dict[newKey] = value; // or dict.Add(newKey, value) depending on ur comfort
return true;
}
你喜欢这个简单的代码吗
var newDictionary= oldDictionary.ReplaceInKeys<object>("_","-");
它将所有密钥中的
'_'
替换为'-'
如果
- 您的
key
类型为string
和
- 您希望在字典的所有键中将字符串替换为其他字符串
然后使用我的方式
你只需要将以下类添加到你的应用程序中:
public static class DicExtensions{
public static void ReplaceInKeys<TValue>(this IDictionary<string, TValue> oldDictionary, string replaceIt, string withIt)
{
// Do all the works with just one line of code:
return oldDictionary
.Select(x=> new KeyValuePair<string, TValue>(x.Key.Replace(replaceIt, withIt), x.Value))
.ToDictionary(x=> x.Key,x=> x.Value);
}
}
我使用Linq更改字典键(通过
linq
重新生成字典)神奇的步骤是
ToDictionary()
方法。
注意:我们可以使高级选择包含用于复杂情况的代码块,而不是简单的lambda。
Select(item =>{
.....Write your Logic Codes Here....
return resultKeyValuePair;
})
实现更改键结果的简单方法(如果需要批量更改)是使用System投影一个新字典。Linq:
var rehashedDictionary = existingDictionary.ToDictionary(kvp => $"newkey-{kvp.Key}", kvp => kvp.Value);
如果您正在处理大型集合,您可能希望使用更专业的性能。
KeyValuePair
保持它们的顺序,直到删除一个条目。移除的钥匙位置之后的所有钥匙都会向上移动一个位置。
但是,您可以使用Linq和扩展方法来生成一个昂贵的但通用的函数,该函数可以重命名键,并维护顺序和值引用。
我想重申,这是非常昂贵的,并且不应该在循环中使用。当需要不频繁的重命名时,请使用此选项。
using System.Linq;
public static class DictionaryExtensions
{
///<Summary> A relatively expensive operation to rename keys</Summary>
public static void RenameKey<TKey, TValue>(this Dictionary<TKey, TValue> dict, TKey from, TKey to)
{
Dictionary<TKey, TValue> temp = new Dictionary<TKey, TValue>(dict);
dict.Clear();
for(int i = 0; i < temp.Count; i++)
{
var kvp = temp.ElementAt(i);
if(kvp.Key.Equals(from))
dict.Add(to, temp[from]);
else
dict.Add(kvp.Key, kvp.Value);
}
}
}
用法:
dict.RenameKey(oldName, newName);
类似于nawfal的答案,不同之处在于只有当两个条件都为真时才更改密钥:
- 旧密钥存在
- 新密钥不存在
/// <summary>Attempts to change the key of a value in the dictionary.</summary>
public static bool TryChangeKey<TKey, TValue>(
this Dictionary<TKey, TValue> source, TKey oldKey, TKey newKey, out TValue value)
{
if (source.ContainsKey(newKey)) { value = default; return false; }
if (!source.Remove(oldKey, out value)) return false;
source.Add(newKey, value);
return true;
}
用法:
if (myDictionary.TryChangeKey(oldKey, newKey, out var value))
{
Console.WriteLine($"Key of {value} changed from {oldKey} to {newKey}.");
}