简体   繁体   English

从列表中删除重复的元素<String>

[英]Remove duplicated elements from a List<String>

I would like to remove the duplicate elements from a List. 我想从列表中删除重复的元素。 Some elements of the list looks like this: 列表的一些元素如下所示:

Book  23
Book  22
Book  19
Notebook 22
Notebook 19
Pen 23
Pen 22
Pen 19

To get rid of duplicate elements i've done this: 为了摆脱重复的元素,我已经完成了这个:

List<String> nodup = dup.Distinct().ToList();

I would like to keep in the list just 我想保留在列表中

Book 23
Notebook 22
Pen 23

How can i do that ? 我怎样才能做到这一点 ?

you can do someting like 你可以做些喜欢的事

string firstElement = dup.Distinct().ToList().First();

and add it to another list if you want. 并根据需要将其添加到另一个列表中。

It's not 100% clear what you want here - however... 它不是100%清楚你想要的 - 但是......

If you want to keep the "largest" number in the list, you could do: 如果要保留列表中的“最大”数字,可以执行以下操作:

List<string> noDup = dup.Select(s => s.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries)
        .Select(p => new { Name=p[0], Val=int.Parse(p[1]) })
        .GroupBy(p => p.Name)
        .Select(g => string.Join(" ", g.Key, g.Max().ToString()))
        .ToList();

This would transform the List<string> by parsing the numeric portion into a number, taking the max per item, and creating the output string as you have specified. 这将通过将数字部分解析为数字,获取每个项目的最大值,并按照您指定的方式创建输出字符串来转换List<string>

You can use LINQ in combination with some String operations to group all your itemy by name and MAX(Number) : 您可以将LINQ与一些String操作结合使用,按名称和MAX(Number)对所有项目进行分组:

var q = from str in list
        let Parts = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
        let item = Parts[ 0 ]
        let num = int.Parse(Parts[ 1 ])
        group new  { Name = item, Number = num } by item into Grp
        select new {
            Name  = Grp.Key,
            Value = Grp.Max(i => i.Number).ToString()
        };

var highestGroups = q.Select(g => 
    String.Format("{0} {1}", g.Name, g.Value)).ToList();

(Same as Reed's approach but in query syntax which is better readable to my mind) (与Reed的方法相同,但在查询语法中,我的脑海中更易读)

Edit : I cannot reproduce your comment that it does not work, here is sample data: 编辑 :我无法重现您的评论它不起作用,这里是示例数据:

List<String> list = new List<String>();
list.Add("Book  23");
list.Add("Book  22");
list.Add("Book 19");
list.Add("Notebook  23");
list.Add("Notebook  22");
list.Add("Notebook  19");
list.Add("Pen  23");
list.Add("Pen  22");
list.Add("Pen  19");
list.Add("sheet 3");

var q = from str in list
        let Parts = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
        let item = Parts[ 0 ]
        let num = int.Parse(Parts[ 1 ])
        group new  { Name = item, Number = num } by item into Grp
        select new {
            Name  = Grp.Key,
            Value = Grp.Max(i => i.Number).ToString()
        };

var highestGroups = q.Select(g => String.Format("{0} {1}", g.Name, g.Value));
MessageBox.Show(String.Join(Environment.NewLine, highestGroups));

The result: 结果:

Book 23
Notebook 23
Pen 23
sheet 3

You may want to add a custom comparer as a parameter, as you can see in the example on MSDN . 您可能希望将自定义比较器添加为参数,如MSDN上的示例所示

In this example I assumed Foo is a class with two members. 在这个例子中,我假设Foo是一个有两个成员的类。

class Program
{
    static void Main(string[] args)
    {
        var list = new List<Foo>()
        {
            new Foo("Book", 23),
            new Foo("Book", 22),
            new Foo("Book", 19)
        };

        foreach(var element in list.Distinct(new Comparer()))
        {
            Console.WriteLine(element.Type + " " + element.Value);
        }
    }
}

public class Foo
{
    public Foo(string type, int value)
    {
        this.Type = type;
        this.Value = value;
    }

    public string Type { get; private set; }

    public int Value { get; private set; }
}

public class Comparer : IEqualityComparer<Foo>
{
    public bool Equals(Foo x, Foo y)
    {
        if(x == null || y == null)
            return x == y;
        else
            return x.Type == y.Type;
    }

    public int GetHashCode(Foo obj)
    {
        return obj.Type.GetHashCode();
    }
}

This works on an IList , assuming that we want the first item each , not the one with the highest number. 这适用于IList ,假设我们需要每个第一个项目 ,而不是具有最高编号的项目。 Be careful with different collection types (like ICollection or IEnumerable ), as they do not guarantee you any order. 请注意不同的集合类型(如ICollectionIEnumerable ),因为它们不保证您有任何订单。 Therefore any of the Foo s may remain after the Distinct . 因此,任何Foo可能在Distinct之后保留。

You could also override both Equals and GetHashCode of Foo instead of using a custom IEqualityComparer . 您还可以覆盖Foo EqualsGetHashCode ,而不是使用自定义IEqualityComparer However, I would not actually recommend this for a local distinct. 但是,我实际上并不建议将其用于本地区域。 Consumers of your class may not recognize that two instances with same value for Type are always equal, regardless of their Value . 您的类的消费者可能无法识别具有相同Value Type两个实例始终相等,无论其Value如何。

a bit old fashioned , but it should work , If I understand correctrly 有点老式,但它应该工作,如果我理解正确

    Dictionary<string,int> dict=new Dictionary<string,int>();

    //Split accepts 1 character ,assume each line containes key value pair seperated with spaces and not containing whitespaces
    input=input.Replace("\r\n","\n");
    string[] lines=input.Split('\n');

    //break to categories and find largest number at each 
    foreach(line in lines)
    {
        string parts[]=line.Split(' ');
        string key=parts[0].Trim();
        int value=Convert.ToInt32(parts[1].Trim());

        if (dict.ContainsKey(key))
        {
            dict.Add(key, value);
        }
        else
        {
            if (dict[key]<value)
            {
                    dict[key]=value;
            }
        }

    }


    //do somethig with dict 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM