删除出现多于一次的列表元素 [英] Remove List Elements that appear more than Once In Place

查看:84
本文介绍了删除出现多于一次的列表元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个类似的问题发布,但是我没有代表在那个线程中问一个后续问题:(

该问题和解决方案是 HERE .

如果我有一个列表,其中包含重复出现的项目,则List.Distinct()将删除重复项,但原始副本仍将保留在原位.如果我想删除重复出现的项目(包括原始项目),最有效的方法是将其删除到原始列表"中?

给出一个名为oneTime的列表: { 4, 5, 7, 3, 5, 4, 2, 4 }

所需的输出将在oneTime中: { 7, 3, 2 }

感谢您的帮助!

----编辑并关注@enigmativity的问题,2016年4月8日-----------------

这是我的脚本正在执行的伪版本.它是在.NET3.5上运行的NinjaTrader中完成的.

我将附上代码应该做的一般性想法,我将附上实际脚本,但是除非使用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

解决方案

因此,如果您可以拥有一个新列表,则这是最简单的方法:

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

There is a similar question posted, but I do not have the rep to ask a follow-up question in that thread :(

That question and solution is HERE.

If I have a List that contains items that appear more than once, List.Distinct() will remove duplicates, but the original will still remain in place. If I want to remove items that occur more than once, including the original, what would be the most efficient way to do this to the ORIGINAL List?

Given a List called oneTime: { 4, 5, 7, 3, 5, 4, 2, 4 }

The desired output would be in oneTime: { 7, 3, 2 }

Thanks for any help!

----Edit and Follow up question for @enigmativity, 8April2016-----------------

Here is a pseudo version of what my script is doing. It is done in NinjaTrader which runs on .NET3.5.

I will attach a general idea of what the code is supposed to be doing, I'd attach the actual script but unless using NinjaTrader, it might not be of use.

But essentially, there is a large z loop. Each time through, a series of numbers is added to 'LiTics.' Which I do not want to disturb. I then pass that list to the function, and return a list of values that only occur once. Then I'd like to see those numbers each time through the loop.

It works initially, but running this on various sets of data, after a few passes through the loop, it start reporting values that occur more than once. I'm not sure why exactly?

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;

}

A picture of the print out and what is going wrong: http://i.stack.imgur.com/pXcdK.jpg

解决方案

So, if you can have a new list, then this is the easiest way to do it:

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

This gives:

{ 7, 3, 2 }

If you want to remove the values from the original source, then do this:

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

这篇关于删除出现多于一次的列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆