Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Linq Distinct仅在下一行中匹配_C#_.net_Linq - Fatal编程技术网

C# Linq Distinct仅在下一行中匹配

C# Linq Distinct仅在下一行中匹配,c#,.net,linq,C#,.net,Linq,我有一个包含以下信息的数据表: 365.00 370.00 369.59 365.00 365.00 -> match with previous item 365.00 -> match with previous item 我只需要删除下一个匹配项,如下所示: 365.00 370.00 369.59 365.00 我试过: (from articlespricehistory in dt.AsEnumerable() select new { articleprice

我有一个包含以下信息的数据表:

365.00
370.00
369.59
365.00
365.00 -> match with previous item
365.00 -> match with previous item
我只需要删除下一个匹配项,如下所示:

365.00
370.00
369.59
365.00
我试过:

(from articlespricehistory in dt.AsEnumerable()
select new
{
   articlepricehistory_cost = articlespricehistory.Field<Double>("articlepricehistory_cost")
})
.DistinctBy(i => i.articlepricehistory_cost)
.ToList();

有什么想法吗?

查询中的问题是您使用的是
.DistinctBy()
,它只会返回不同的结果。因此,如果365.00出现在任何地方,它将不会再次出现在返回的列表中

var differentPreviousList = new List<double>();
var itemPriceList = dt.ToList();
differentPreviousList.Add(itemPriceList[0]);
for (var index = 1; index < itemPriceList.Count; index++)
{
    if (itemPriceList[index - 1] == itemPriceList[index]) continue;
    differentPriceList.Add(itemPriceList[index]);
}
var differentitprevouslist=newlist();
var itemPriceList=dt.ToList();
DifferentipPreviousList.Add(itemPriceList[0]);
对于(var index=1;index
有一个想法我还没有尝试过

  • 对查询执行
    跳过(1)
    ,以生成第二个查询
  • 现在,将不等于第一个查询中最后一个元素的任何元素附加到第二个查询,以生成第三个查询
  • 现在,将第一个和第三个查询压缩连接在一起,形成一组查询对;这是第四个问题
  • 现在构造第五个查询,从第四个查询中筛选出具有相同元素的对
  • 最后,构造第六个查询,从第五个查询中选择每对中的第一个元素

第六个查询是您想要的数据集。

我认为您必须使用一个临时值来检查下一个值是否与当前值匹配

double temporary = -1;  // temp value for checking
List<double> results = new List<double>(); // list to store results

(from articlespricehistory in dt.AsEnumerable()
 select new
 {
    articlepricehistory_cost = articlespricehistory.Field<Double>("articlepricehistory_cost")
 })
  .Select(a => a.articlepricehistory_cost)
  .ToList()
  .ForEach(cost => 
  {
      if (temporary != cost) { results.Add(cost); }
      temporary = cost;
  });

foreach (var result in results)
{
    Console.WriteLine(result);
}
另一种方法:

public static IEnumerable<T> MyDistinct<T>(this IEnumerable<T> items) 
{
    T previous = default(T);
    bool first = true;
    foreach(T item in items)
    {
        if (first || !Equals(previous, item)) 
        {
            first = false;
            previous = item;
            yield return item;
        }
    }
} 
公共静态IEnumerable MyDistinct(此IEnumerable项)
{
T先前=默认值(T);
bool first=true;
foreach(项目中的T项目)
{
如果(第一个| |!等于(上一个,项目))
{
第一个=假;
先前=项目;
收益回报项目;
}
}
} 
或者,根据要求,使用选择器

public static IEnumerable<T> MyDistinct<T, U>(this IEnumerable<T> items, Func<T, U> selector) 
{
    U previous = default(U);
    bool first = true;
    foreach(T item in items)
    {
        U current = selector(item);
        if (first || !Equals(previous, current)) 
        {
            first = false;
            previous = current;
            yield return item;
        }
    }
} 
公共静态IEnumerable MyDistinct(此IEnumerable项,Func选择器)
{
U先前=默认值(U);
bool first=true;
foreach(项目中的T项目)
{
U电流=选择器(项目);
如果(第一个| |!等于(上一个,当前))
{
第一个=假;
先前=当前;
收益回报项目;
}
}
} 

这是一个简洁的LINQ解决方案,适用于

var list = (dt as Enumerable);

var numbers = list.TakeWhile((currentItem, index) => currentItem != list.ElementAtOrDefault(index - 1));

请记住,如果您将0作为第一个元素,那么它将从新列表中删除,因为ElementAtOrDefault将在while循环的第一次迭代中返回0(索引为-1),从而将表达式计算为false。一个简单的if语句可以帮助您避免这种情况。

这可能不是一个优雅的解决方案,但我只想解析一个简单的查询。.下面是如何解决的

  • 运行lambda查询以获取所有原始结果,而无需尝试筛选出DistinctBy
  • 创建初始查询类型的单个查询结果的对象
  • 初始化foreach解析结果的新列表
  • 对每个结果对每个循环执行一次测试
  • 第一个if部分应该是if(循环上方的对象为null)
  • 如果为true,则将项目添加到列表中
  • ELSE if检查项的值是否与上一次迭代相同
  • 将foreach迭代对象存储到循环之前声明的对象

  • 清洗并重复,结果是循环中的一行中没有发现重复的对象将存储在列表中,从而得到您想要的结果。

    如果要使用包含语句的
    ForEach
    来修改临时变量,为什么不简单地修改它下面的
    ForEach
    循环?您是对的。我的代码相当于使用foreach循环。我添加了另一个版本。我使用ForEach方法只是为了避免像往常一样将第一个结果设置为新列表。谢谢。你依赖foreach来维持秩序的原因是什么?为什么谢谢你的回答,所以你知道我如何给这个表达式添加选择器吗?像这样:
    .MyDistinct(i=>i.articleprichestory\u cost)
    因为我只需要比较一个column@displayName例如我不明白这个问题。你能澄清一下吗?@displayName:我还是不明白这个问题。循环按照可枚举项确定的顺序枚举可枚举项;这就是可枚举的含义。如果您不喜欢该顺序,请与可枚举对象的提供程序联系。@displayName:很乐意提供帮助。我经常在这里总结Brian的观点,一个查询表达式代表一个问题,而不是一个答案。枚举查询实际上是问问题;每次提问时,问题的答案是否相同取决于问题是什么以及你问的是谁。我注意到,如果你必须引入一个注释来解释代码,那么代码就不够清晰。为什么不简单地说
    TakeWhile((currentItem,index)=>…
    并删除注释呢?
    public static IEnumerable<T> MyDistinct<T, U>(this IEnumerable<T> items, Func<T, U> selector) 
    {
        U previous = default(U);
        bool first = true;
        foreach(T item in items)
        {
            U current = selector(item);
            if (first || !Equals(previous, current)) 
            {
                first = false;
                previous = current;
                yield return item;
            }
        }
    } 
    
    var list = (dt as Enumerable);
    
    var numbers = list.TakeWhile((currentItem, index) => currentItem != list.ElementAtOrDefault(index - 1));