只在下一行匹配中不同

本文关键字:一行 | 更新日期: 2023-09-27 18:17:15

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

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();
结果:

365.00
370.00
369.59

任何想法?

只在下一行匹配中不同

另一种方法:

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;
        }
    }
} 

或者,根据请求,使用选择器

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;
        }
    }
} 

这是一个简洁的LINQ解决方案

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

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

这是一个我实际上没有尝试过的想法

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

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

查询中的问题是您正在使用.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]);
}

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

  1. 运行lambda查询以获得所有原始结果,而不尝试过滤掉DistinctBy。
  2. 为您最初查询的类型创建单个查询结果的对象。
  3. 为每个解析结果初始化一个新的列表
  4. 为每个结果的每个循环执行a。
  5. 第一个if部分应该是if(object above loop is null)。
  6. 如果为真,将项目添加到列表
  7. ELSE if检查item的值是否与上一次迭代相同。
  8. 将每个迭代对象存储到循环前声明的对象。

循环并重复,结果是在循环中的一行中没有发现重复的对象,将被存储在列表中,从而产生您想要的

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

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);
}

ForEach方法等效如下:

foreach (var cost in costs)
{
    if (temporary != cost)
    {
        results.Add(cost);
        Console.WriteLine(cost);
    }
    temporary = cost;
}