发布了一个类似的问题,但我没有代表在该帖子中询问后续问题:(
该问题和解决方案是HERE。
如果我的列表包含多次出现的项目,List.Distinct()
将删除重复项,但原始文件仍会保留。如果我想删除多次出现的项目,包括原始项目,那么对ORIGINAL列表执行此操作的最有效方法是什么?
给定名为oneTime的List:
{ 4, 5, 7, 3, 5, 4, 2, 4 }
所需的输出将在oneTime中:
{ 7, 3, 2 }
感谢您的帮助!
---- @enigmativity的编辑和跟进问题,8月18日-----------------
这是我的脚本正在做的伪版本。它是在NinjaTrader中完成的,它运行在.NET3.5上。
我将附上代码应该做的一般概念,我会附上实际的脚本,但除非使用NinjaTrader,否则它可能没有用。
但实质上,有一个大的z循环。每一次,“LiTics”都会添加一系列数字。哪个我不想打扰。然后我将该列表传递给函数,并返回仅出现一次的值列表。然后,我希望每次都能看到这些数字。
它最初工作,但是在各种数据集上运行它,经过几次循环后,它开始报告多次出现的值。我不确定为什么呢?
for(int z=1; z<=10000; z +=1)//Runs many times
{
if (BarsInProgress ==0 &&CurrentBar-oBarTF1>0 &&startScript ) //Some Condition
{
for(double k=Low[0]; k<=High[0]; k +=TickSize)
{
LiTics.Add(k);
//Adds a series of numbers to this list each time through z loop
//This is original that I do not want to disturb
}
LiTZ.Clear(); //Display list to show me results Clear before populating
LiTZ=GetTZone(LiTics); //function created in thread(below)
//Passing the undisturbed list that is modified on every loop
foreach (double prime in LiTZ) { Print(Times[0] +", " +prime); }
//Printing to see results
}
}//End of bigger 'z' loop
//Function created to get values that appear ONLY once
public List<double> GetTZone(List<double> sequence)
{
var result =
sequence
.GroupBy(x => x)
.Where(x => !x.Skip(1).Any())
.Select(x => x.Key)
.ToList();
return result;
}
打印输出的图片以及出错的地方: http://i.stack.imgur.com/pXcdK.jpg
答案 0 :(得分:4)
所以,如果你有一个新列表,那么这是最简单的方法:
var source = new List<int>() { 4, 5, 7, 3, 5, 4, 2, 4 };
var result =
source
.GroupBy(x => x)
.Where(x => !x.Skip(1).Any())
.Select(x => x.Key)
.ToList();
这给出了:
{ 7, 3, 2 }
如果要从原始源中删除值,请执行以下操作:
var duplicates =
new HashSet<int>(
source
.GroupBy(x => x)
.Where(x => x.Skip(1).Any())
.Select(x => x.Key));
source.RemoveAll(n => duplicates.Contains(n));
答案 1 :(得分:-1)
我有两个选项,一个使用HashSet
和其他Linq
。
选项1:
使用HashSet
,循环收集并插入(如果不存在)并删除它是否存在。
HashSet<int> hash = new HashSet<int>();
foreach(var number in list)
{
if(!hash.Contains(number)) hash.Add(number);
else hash.Remove(number);
}
list = hash.ToList();
选项2:
简单Linq,
对其计数为>1
的元素和过滤器进行分组。
var list= list.GroupBy(g=>g)
.Where(e=>e.Count()==1)
.Select(g=>g.Key)
.ToList();
使用HashSet
而不是Linq
有大性能增益,显而易见,Linq
(在这种情况下)需要多次迭代,其中HashSet
1}}使用单次迭代并通过O(1)
访问提供LookUp(用于添加/删除)。
Elapsed Time (Using Linq): 8808 Ticks
Elapsed Time (Using HashSet): 51 Ticks
工作Demo