添加到 KeyValuePair 的 HashSet

Addition on HashSet of KeyValuePair

我有一个条目列表。每个条目都包含一个字符串和一个数值。同一个字符串可以在列表中出现一次或多次,并且可以有不同的数值。因为我正在寻找一种优雅的方式来处理列表。最终结果应该是唯一的字符串对列表和(字符串值的总和)。每个唯一的字符串应该与该字符串的所有数值的总和相关联。我考虑创建一个 HashSet> 并将每个字符串添加到 HashSet。但我不确定如何在一个循环中将所有值加在一起。下面的代码有效,但效率低下。

        SortedSet<string> symbols = new SortedSet<string>();
        HashSet<KeyValuePair<string, double>> results = new HashSet<KeyValuePair<string, double>>();
        string file = openFileDialog1.FileName;
        string[] lines = File.ReadAllLines(file);
        
        foreach(string line in lines) {
            string[] values = line.Split('\t');
            string symbol = values[0].Trim();
            symbols.Add(symbol);
        }
        
        foreach(string uniqueSymbol in symbols) {
            double value = 0;
            foreach(string line in lines) {
                string[] values = line.Split('\t');
                string symbol = values[0].Trim();
                string sProfit = values[7].Trim();
                double fProfit = Convert.ToDouble(sProfit);
                
                if(symbol == uniqueSymbol) {
                    value += fProfit;
                }
            }
            
            results.Add(new KeyValuePair<string, double>(uniqueSymbol, value));
        }

如果我了解到您想获得重复行值的总和,这可能会有所帮助。

Dictionary<string, double> results = new Dictionary<string, double>();
foreach(string line in lines) {
            string[] values = line.Split('\t');
            string symbol = values[0].Trim();
            double profit = Convert.ToDouble(values[7].Trim());
            results.Add(symbol, profit);
}

List<KeyValuePair<string, double>> grouped = (from kvp in results 
                                             group kvp by kvp.Key
                                             into g
                                             select
                                             new KeyValuePair<string, double> 
                                             (g.Key,g.Sum(e => e.Value))) 
.ToList();

我不确定为什么您需要使用 HashSet 来处理某些 看起来 适合 Dictionary 的工作。

下面是我将如何填充这样一个字典:

Dictionary<string, double> result = new Dictionary<string, double>();

foreach (string line in lines)
{
    string[] values = line.Split(“\t”);
    string symbol = values[0].Trim();
    double profit = Convert.ToDouble(values[7].Trim());
    result.TryGetValue(symbol, out double _profit);
    result[symbol] = _profit + profit;
}

如果您需要将它们提取到 HashSet 中,那应该很容易。

和这里的其他几个人一样,我同意 Dictionary 听起来最适合您的需求。如果使用 Linq 是一个选项,这里有一个应该有效的方法:

Dictionary<string, double> results = lines
    .Select(line => line.Split('\t'))
    .Select(lineEntries => (
        Symbol: lineEntries[0].Trim(), 
        Value: Convert.ToDouble(lineEntries[7].Trim()))) // Some validation should be done here
    .GroupBy(symbolAndValue => symbolAndValue.Symbol)
    .ToDictionary(
        gr => gr.Key,
        gr => gr.Select(symbolAndValue => symbolAndValue.Value).Sum());

我正在为每个 line 创建一个元组 (string Symbol, double Value),然后按 Symbol 对它们进行分组,然后使用 Symbol 作为 Key 创建一个字典] 和连接到 Symbol 的值的总和作为每个字典条目的 Value


一种稍微更简洁的方法是通过执行两次 line.Split('\t') 将两个 Select 语句合并在一起:

.Select(line => (
    Symbol: line.Split('\t')[0].Trim(), 
    Value: Convert.ToDouble(line.Split('\t')[7].Trim())))