[英]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. 请注意不同的集合类型(如ICollection
或IEnumerable
),因为它们不保证您有任何订单。 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
Equals
和GetHashCode
,而不是使用自定义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.