我有IEnumerable
IEnumerable<Pets> pets;
它由
组成public string Name { get; set; }
public string Other { get; set; }
public decimal? Price { get; set; }
我想迭代这一点,找到所有重复的价格,并将这些重复的价格设置为空。
说一只猫和一只狗的价格相同:10.55。我想保留第一个,但删除所有剩余价格。
答案 0 :(得分:2)
方式:
1)删除重复项(我推荐):
var filtered = pets.GroupBy(pet => pet.Price).Select(group => group.First());
2)排序&amp; evalute - 根据需要设置null代替重复项(你确定要设置空值而不是像1中那样删除吗?)。
var newPets = pets.OrderBy(per => pet.Price).ToList();
if (!newPets.Any()) return newPets;
var last = 0;
for (var i = 1; i < newPets.Count; i++)
{
if (newPets[i].Price == newPets[last].Price) newPets[i] = null;
else last = i;
}
return newPets;
我认为在这种情况下排序就足够了:O(n * log n) + O(n)
针对自定义迭代中的O(n^2)
来搜索每个元素的重复项。
3)经典方式(没有排序,最慢)
var newPets = pets.ToList();
for (var i = 0; i < newPets.Count; i++)
{
if (newPets[i] == null) continue;
var price = newPets[i].Price;
for (var j = i + 1; j < newPets.Count; j++)
{
if (newPets[j].Price == price) newPets[j] = null;
}
}
正如 D Stanley 已注意到(但我已经错过了),您可能需要将Price
设置为null
而不是整个记录。然后只需将其更改为decimal?
,然后写入newPets[i].Price = null;
而不是整个记录。
答案 1 :(得分:1)
对于初学者来说,decimal
不能为空,所以我会回答它,好像你有一个decimal?
类型,这样你才能理解这个过程。
Linq用于查询,而非更新。您可以根据原始广告投放新集合,但foreach
可能更合适:
// list to keep tack of found prices
var prices = new List<decimal>();
foreach(Pet pet in pets)
{
if(prices.Contains(pet.Price.Value))
// price was found - set this one to null
pet.Price = null;
else
// add to the list of "found" prices
prices.Add(pet.Price.Value);
}
答案 2 :(得分:1)
public class Pet
{
public string Name { get; set; }
public string Other { get; set; }
public decimal? Price { get; set; }
}
请注意,价格现在可以为空(decimal?
)
return pets
.OrderBy(x => x.Name)
.GroupBy(x => x.Price)
.OrderBy(x => x.Key)
.SelectMany(x => (new[] { x.First() }).Union(x.Skip(1).Select(n => new Pet { Name = n.Name, Other = n.Other, Price = null })))
.ToList();