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语句可以帮助您避免这种情况。这可能不是一个优雅的解决方案,但我只想解析一个简单的查询。.下面是如何解决的
清洗并重复,结果是循环中的一行中没有发现重复的对象将存储在列表中,从而得到您想要的结果。如果要使用包含语句的
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));