如何在字典中将键和值进行交换

8

大家好,我想要交换字典中的键和值。

我的字典长这样:

public static void Main(string[] args)
{
Dictionary<int,int> dic = new Dictionary<int,int>{{1,10}, {2, 20}, {3, 30}};
}

现在我正在从字典中打印值

 foreach (KeyValuePair<int, int> kvp in dic)
{

    Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
            Console.ReadKey();
}

我在显示器上看到了这个信息

Key = 1, Value = 10
Key = 2, Value = 20
Key = 3, Value = 30

我希望你能帮我交换键和值之间的数值。交换后,答案应该是这样的:
Key = 10, Value = 1
Key = 20, Value = 2
Key = 30, Value = 3

我曾使用lambda表达式来完成某项任务,但是我需要其他方法来实现同样的功能。


3
你想要交换实际字典中的键和值吗?还是只是打印交换后的结果?"键 = {1},值 = {0}" - Josh Adams
1
你确定所有的值都是唯一的吗(根据字典“合同”,它们不需要是唯一的)?如果不是,你希望如何处理这种情况? - Damien_The_Unbeliever
如果您有多个键具有相同的值,该怎么办? - Rafalon
1
不确定为什么你想要这个交换。直接使用字典即可。你是在尝试解决一个测试吗? - Alpesh
我想在实际字典中进行交换 @JoshAdams - Babu
显示剩余4条评论
4个回答

30

假设值是唯一的,这将起作用:

var dic = new Dictionary<int,int>{{1,10}, {2, 20}, {3, 30}};

var dic2 = dic.ToDictionary(x => x.Value, x=> x.Key);

它实际上不会交换字典中的键值对,而是会生成一个新的字典。


兄弟,我不想创建新的字典。在实际字典中交换值。 - Babu
2
你不能这样做。你为什么认为你需要那个?如果两边都是相同类型的,你可以尝试在现有条目后添加“交换”的条目,然后再删除它们。但是这样做并没有任何作用。 - ZorgoZ
Key 是只读的。你可以在创建这个额外的字典后,清空原始字典并将所有条目从新字典中添加进去。 - Ofir Winegarten

0

这里有一个扩展,让你可以做到:

Dictionary<int, int> newDic = oldDic.SwapKeysAndValues();



    /// <summary>
    /// Take a dictionary and make the values the keys and the keys the values
    /// </summary>
    /// <typeparam name="K">The original dictionary key type</typeparam>
    /// <typeparam name="V">The original value type</typeparam>
    /// <param value="dictionary<K, V>"></param>
    /// <returns>Dictionary<V, K></returns>
    public static Dictionary<V, K> SwapKeysAndValues<K, V>(this Dictionary<K, V> original)
    {
        Dictionary<V, K> result = new Dictionary<V, K>();
        foreach (V value in original.Values.Distinct())
        {
            result.Add(value, original.First(x => x.Value.Equals(value)).Key);
        }

        // optional
        //if(original.Count > result.Count)
        //{
        //  throw new Exception("Duplicate value ignored ");
        //}


        return result;
    }

0

我进行了速度测试,发现如果有超过一小部分的项,则创建一个没有指定容量的新字典要慢得多。事实上,在1000个项目时它慢了约30%*。此外,如果键和值是相同类型,您可能还希望在相反方向使用相同的IEqualityComparer。最后,如果您有一个重复的值,则Linq版本会抛出错误。

这个版本基本上与Linq版本相同,但增加了如果可能使用相同的IEqualityComparer,设置初始容量并防止潜在的重复错误:

var dic = new Dictionary<int, int>() { { 1, 10 }, { 2, 20 }, { 3, 30 } };
var dic2 = dic.ToDictionarySwapped();

Console.WriteLine(String.Join(",", dic.Select(i => i.Key + ":" + i.Value)));
Console.WriteLine(String.Join(",", dic2.Select(i => i.Key + ":" + i.Value)));

public static Dictionary<V, K> ToDictionarySwapped<K, V>(this Dictionary<K, V> original, bool useSameComparerIfPossible = true)
{
    IEqualityComparer<V> comparer = null;
    if (useSameComparerIfPossible && typeof(K) == typeof(V)) comparer = (IEqualityComparer<V>)original.Comparer;
    var swapped = new Dictionary<V, K>(capacity: original.Count, comparer: comparer);
    foreach (var item in original) swapped[item.Value] = item.Key;
    return swapped;
}

我运行的测试是一个循环,交换包含1000个项目的字典1000次。测试分别在设置容量和未设置容量的情况下重复进行。当设置容量时,我的平均时间约为65毫秒,而当未设置容量时,约为95毫秒。测试是在发布模式下编译后运行的。

-3

我认为你会理解下面的代码:

namespace Swap
{
public class Class1
{
    public SortedDictionary<string, string> names;

    public void BeforeSwaping()
    {
        Console.WriteLine("Before Swapping: ");
        Console.WriteLine();
        names = new SortedDictionary<string, string>();
        names.Add("Sonoo", "srinath");
        names.Add("Perer", "mahesh");
        names.Add("James", "ramesh");
        names.Add("Ratan", "badri");
        names.Add("Irfan", "suresh");
        names.Add("sravan", "current");
        foreach (KeyValuePair<string, string> item in names)
        {

            Console.WriteLine("Key: {0}, Value: {1}", item.Key, item.Value);

        }
        Console.WriteLine();
    }

    public void AfterSwaping()
    {
        Console.WriteLine("After Swapping: ");
        Console.WriteLine();
        var key = names.Keys;
        var val = names.Values;

        string[] arrayKey = new string[key.Count];
        string[] arrayVal = new string[val.Count];
        int i = 0;
        foreach (string s in key)
        {
            arrayKey[i++] = s;
        }
        int j = 0;
        foreach (string s in val)
        {
            arrayVal[j++] = s;
        }
        names.Clear();
        //Console.WriteLine(arrayVal[0] + " " + arrayKey[0]);
        for (int k = 0; k < (arrayKey.Length + arrayVal.Length) / 2; k++)
        {
            names.Add(arrayVal[k], arrayKey[k]);
        }
        foreach (KeyValuePair<string, string> s in names)
        {
            Console.WriteLine("key:"+s.Key + ", "+"value:" + s.Value);
        }
    }
    public static void Main(string[] args)
    {
        Class1 c = new Class1();
        c.BeforeSwaping();
        c.AfterSwaping();
        Console.ReadKey();
    }
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接