通过值差异加入两个词典

时间:2013-12-29 13:05:56

标签: c# linq

我有这两个词典:

Dictionary<char, double> analyzed_symbols = new Dictionary<char, double>();
Dictionary<char, double> decode_symbols = new Dictionary<char, double>();

我需要创建另一个应该将键作为键和值的字典,如下所示:

Dictionary<char, char> replace_symbols = new Dictionary<char, char>();

“加入”它们的条件是值之间的差异应该是最小的,如下所示:

Math.Min(Math.Abs(analyzed_symbols[key] - decode_symbols[key]))

我想我应该为此目的使用LINQ,但无法弄清楚如何正确编写查询。

数据样本:

analyzed_symbols = [a, 173], [b, 1522], [z, 99]
decode_symbols = [в, 100], [д, 185], [e, 1622]

对于这些dicts,输出数据应如下所示:

replace_symbols = [z, в], [b, е], [a, д]

我发现question非常接近我的需要,但并不完全正确。斯诺伊要求一个接近的值,但我需要为两个字典做同样的事情。

3 个答案:

答案 0 :(得分:1)

这是我的看法:

var analyzed_symbols = new Dictionary<char, double>(){ {'a', 173}, {'b', 1522}, {'z', 99} };
var decode_symbols = new Dictionary<char, double>(){ {'в', 100}, {'д', 185}, {'e', 1622} };

var q = from a in analyzed_symbols
        from d in decode_symbols
        let tmp = new { A = a.Key, D = d.Key, Value = Math.Abs(a.Value - d.Value) }
        group tmp by tmp.A into g
        select new
        {
            Key = g.Key,
            Value = g.OrderBy (x => x.Value).Select (x => x.D).First()
        };

var replace_symbols = q.ToDictionary (x => x.Key, x => x.Value);

答案 1 :(得分:0)

好的,我会试试。我分成几个查询,因为它更具可读性。

//sorting values of the dictionaries to easily get closest
var analyzedSortedValues = analyzed_symbols.Values.OrderBy(k => k);
var decodeSortedValues = decode_symbols.Values.OrderBy(k => k);

//creating pairs of the closest values. Here I use iterator index i to skip
//some values that have been used already (is it correct?)
var t = analyzedSortedValues.Select((k, i) => new { a = k, d = decodeSortedValues.Skip(i).Any() ? decodeSortedValues.Skip(i).First() : -1 });

//printing results by getting appropriate keys from corresponding dictionaries       
foreach (var item in t)
{
    Console.WriteLine("[{0}, {1}]", analyzed_symbols.FirstOrDefault(kvp => kvp.Value == item.a).Key, decode_symbols.FirstOrDefault(kvp => kvp.Value == item.d).Key);
}

答案 2 :(得分:0)

我不确定如何通过LINQ来做到这一点,但这里是您想要做的简写版。

private static Dictionary<char, char> BuildReplacementDictionary(Dictionary<char, double> analyzedSymbols,
                                                                 Dictionary<char, double> decodeSymbols)
{
    Dictionary<char, char> replaceSymbols = new Dictionary<char, char>(analyzedSymbols.Count);

    foreach (KeyValuePair<char, double> analyzedKvp in analyzedSymbols)
    {
        double bestMatchValue = double.MaxValue;

        foreach (KeyValuePair<char, double> decodeKvp in decodeSymbols)
        {
            var testValue = Math.Abs(analyzedKvp.Value - decodeKvp.Value);
            if (testValue <= bestMatchValue)
            {
                bestMatchValue = testValue;
                replaceSymbols[analyzedKvp.Key] = decodeKvp.Key;
            }
        }
    }
    return replaceSymbols;
}

它的作用是通过分析字典的每个元素,测试解码字典的每个元素,如果该匹配与前一个匹配相同或更好,它会发现它将使用解码字典中的新值