【问题标题】:Subtract a list of keyvalue by another list of keyvalue用另一个键值列表减去一个键值列表
【发布时间】:2017-12-18 11:12:50
【问题描述】:

有没有办法通过 linq 做事,而不必做一个嵌套的 for 循环和检查键(即下面)

假设:每个列表不包含重复日期

foreach(KeyValuePair value1 in List1)
{
   foreach(KeyValuePair value2 in List2)
   {
        if(value1.Key == Value2.Key)
        {
            .........
        }
        else
        {
           ......
        }
   }
}

我有两个列表

列表1

DateTime, Value
2017/01/01, 5
2017/01/02, 10
2017/01/05, 15

列表2

DateTime, Value
2017/01/01, 1
2017/01/03, 3
2017/01/04, 5

结果必须是(列表 1 - 列表 2)

DateTime, Value
2017/01/01, 4
2017/01/02, 10
2017/01/03, -3
2017/01/04, -5
2017/01/05, 15

【问题讨论】:

  • 你为什么不用KeyValuePair
  • 是的,我只是在线程中手动输入的,所以我发布时错过了它
  • 如果第一个列表包含重复的日期,您也想对这些值求和吗?
  • 嗨,没有重复的日期

标签: c# list linq


【解决方案1】:

如果您想从list1 中减去list2(即加起来list1否定 list2):

   var result = list1
     .Concat(list2
        .Select(pair => new KeyValuePair<DateTime, int>(pair.Key, -pair.Value)))
     .GroupBy(pair => pair.Key, 
              pair => pair.Value)
     .Select(chunk => new KeyValuePair<DateTime, int>(chunk.Key, chunk.Sum()))
     .OrderBy(pair => pair.Key);

【讨论】:

  • 嗨,这很好用,从 sub 更改为 multiply 是一个简单的更改,方法是保持 list1 为正,而不是 chunk.sum() 我做了一个 chunk.Aggregate((e1, e2) => e1 * e2)
  • @UndeadEmo: 非常正确:Concat(可能修改 - 上面代码中的否定),GroupByAggregateSum 或自定义)。
  • 虽然如果 list2 中的 pair.Valueint.MinValue 是一个荒谬的边缘情况,那么当您执行 -pair.Value 时,此代码将溢出。我怀疑这是否会相关,但每当我看到 - 用作一元运算符时,我总是会想到这种极端情况。
  • @Chris:不错的收获!如果存在 溢出 的可能性,则转换为 long 会有所帮助:list1.Select(pair =&gt; new KeyValue&lt;DateTime, long&gt;(pair.Key, pair.Value)).Concat(..new KeyValuePair&lt;DateTime, long&gt;(pair.Key, -(long)pair.Value)))....Select(chunk =&gt; new KeyValuePair&lt;DateTime, int&gt;(chunk.Key, (int)chunk.Sum()));
【解决方案2】:

我认为,在您的情况下,您可以使用简单的 loop 而不是 Linq。此外,它不会像您提到的那样是嵌套的;

        var listA = new List<KeyValuePair<DateTime, int>>()
        {
            new KeyValuePair<DateTime, int>(new DateTime(2017,01,01),15),
            new KeyValuePair<DateTime, int>(new DateTime(2017,01,02),15),
            new KeyValuePair<DateTime, int>(new DateTime(2017, 01, 04), 15),
            new KeyValuePair<DateTime, int>(new DateTime(2017, 01, 05), 15)
        };
        var listB = new List<KeyValuePair<DateTime, int>>()
        {
            new KeyValuePair<DateTime, int>(new DateTime(2017, 01, 01), 10),
            new KeyValuePair<DateTime, int>(new DateTime(2017, 01, 03), 15)
        };
        var listC = new List<KeyValuePair<DateTime, int>>();
        var maxCount = Math.Max(listA.Count, listB.Count);
        for (int i = 0; i < maxCount; i++)
        {
            if (listA.Count < i + 1)
            {
                listC.Add(new KeyValuePair<DateTime, int>(listB[i].Key,-listB[i].Value));
                continue;
            }
            if (listB.Count < i + 1)
            {
                listC.Add(new KeyValuePair<DateTime, int>(listA[i].Key, listA[i].Value));
                continue;
            }
            if (listA[i].Key == listB[i].Key)
            {
                int value = listA[i].Value - listB[i].Value;
                listC.Add(new KeyValuePair<DateTime, int>(listA[i].Key, value));
            }
            else
            {
                listC.Add(new KeyValuePair<DateTime, int>(listA[i].Key, listA[i].Value));
                listC.Add(new KeyValuePair<DateTime, int>(listB[i].Key, -listB[i].Value));
            }
        }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 2021-09-18
    • 2019-11-07
    相关资源
    最近更新 更多