【问题标题】:Need advice for C# LINQ List aggregation expression需要 C# LINQ 列表聚合表达式的建议
【发布时间】:2019-11-06 05:14:33
【问题描述】:

假设我有这个价格类型列表:

[
    {
        "Id": 57571,
        "Price": 1745.0,
        "DateAdded": "2018-12-01T00:00:00"
    },
    {
        "Id": 67537,
        "Price": 1695.0,
        "DateAdded": "2018-09-24T00:00:00"
    },
    {
        "Id": 80042,
        "Price": 1645.0,
        "DateAdded": "2019-03-24T00:00:00"
    },
    {
        "Id": 155866,
        "Price": 1545.0,
        "DateAdded": "2019-04-24T00:00:00"
    },
    {
        "Id": 163643,
        "Price": 1545.0,
        "DateAdded": "2019-04-26T00:00:00"
    },
    {
        "Id": 171379,
        "Price": 1545.0,
        "DateAdded": "2019-04-27T00:00:00"
    },
    {
        "Id": 178990,
        "Price": 1545.0,
        "DateAdded": "2019-04-28T00:00:00"
    }
]

我需要删除所有价格相同的项目,但前提是该项目是列表元素的兄弟。是否可以通过使用 LINQ 来实现这一点?

我的预期输出是

[
    {
        "Id": 57571,
        "Price": 1745.0,
        "DateAdded": "2018-12-01T00:00:00"
    },
    {
        "Id": 67537,
        "Price": 1695.0,
        "DateAdded": "2018-09-24T00:00:00"
    },
    {
        "Id": 80042,
        "Price": 1645.0,
        "DateAdded": "2019-03-24T00:00:00"
    },
    {
        "Id": 155866,
        "Price": 1545.0,
        "DateAdded": "2019-04-24T00:00:00"
    }
]

我完全不知道如何实现这一目标。我很感激任何建议。

【问题讨论】:

  • "但仅当该项目是列表元素的兄弟时" - 所以1, 2, 3, 3, 2, 1 的列表将变为1, 2, 3, 2, 1?
  • @CodeCaster 没错 :)
  • 兄弟姐妹的意思是“相邻”?
  • @mjwills 是的 :)
  • 您认为您可以将源数据和预期结果作为有效的 c# 代码提供吗?

标签: c# list linq aggregation


【解决方案1】:

您可以使用迭代器简单地这样做:

using System;
using System.Collections.Generic;

public class Test
{
    public static void Main()
    {
        var input = new[] { 1, 2, 2, 3, 4, 4, 3, 2, 2, 1 };

        var output = GetUniqueAdjacent(input);

        foreach (var o in output)
        {
            Console.WriteLine(o);
        }
    }

    public static IEnumerable<int> GetUniqueAdjacent(IEnumerable<int> input)
    {
        bool first = true;
        int previous = -1;
        foreach (var i in input)
        {
            if (first)
            {
                previous = i;
                yield return i;
                first = false;
                continue;
            }

            if (i == previous)
            {
                previous = i;
                continue;
            }

            previous = i;
            yield return i;
        }
    }
}

这会输出1, 2, 3, 4, 3, 2, 1,仅当它们相邻时才会删除重复项。

【讨论】:

    【解决方案2】:

    通过使用 Microsoft 的 C# 文档中的 ChunkBy extension 方法,您可以

    myData.ChunkBy(x => x.Price).Select(g => g.First())
    

    ...或者使用MoreLinq's GroupAdjacent你可以

    myData.GroupAdjacent(x => x.Price).Select(g => g.First())
    

    【讨论】:

      【解决方案3】:

      这可以通过常规的Where 调用来完成。

      int? previousPrice = null;
      
      var output = myData.Where(d => {
        var result = !previousPrice.HasValue || previousPrice.Value != d.Price;
        previousPrice = d.Price;
        return result;
      }).ToList();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多