我正在尝试更新对象列表中的所有重复项(如果它们存在于另一个集合中)。
这是我的代码:
public class Cars
{
public string brand { get; set; }
public string model { get; set; }
public string allowed { get; set; }
}
var notAllowedModels = GetNotAllowedModels(); // returns a List<String> with model names
foreach(var car in cars) // cars is a List<Car>
{
if (notAllowedModels.Contains(car.model))
cars[cars.FindIndex(x => x.model == car.model)].allowed = "No";
else
cars[cars.FindIndex(x => x.model == car.model)].allowed = "Yes";
}
如果列表中的模型是唯一的,那么它可以正常工作,但是如果它们存在多次,那么只会更新第一个,而其他模型将为空。
如果notAllowedModels
列表中存在所有重复项,是否有人会想到更新所有重复项的方法?
我知道我可以使用FindAll
代替FindIndex
,但它会返回一个列表,我不确定它对我有多大帮助,因为重复项会出现同样的问题。
答案 0 :(得分:6)
您不需要使用List.FindIndex
来查找汽车,您已经拥有它:
foreach(Car car in cars) // cars is a List<Car>
{
if (notAllowedModels.Contains(car.model))
car.allowed = "No";
else
car.allowed = "Yes";
}
顺便说一句,如果您想提高效果,请从HashSet<string>
返回GetNotAllowedModels
。它只包含唯一值,并且在查找中非常有效(Contains
)。
答案 1 :(得分:1)
您还可以使用Linq Union扩展程序方法查找cars
列表中同样位于notAllowedModels
列表中的所有汽车。
var union = cars.Union(notAllowedModels);
union.ForEach(x => x.allowed = "No");
Union
方法使用默认比较器。因此,您应该重载汽车类的Equals
方法。
在旁注中,对bool
或string
的值使用false
而不是true
类型通常更好,并且使用属性更好而不是让你的成员公开。
public class Car
{
public bool IsAllowed {get;set;}
// rest of your class
}
答案 2 :(得分:0)
您可以使用GroupBy按型号对汽车进行分组,然后检查是否允许该型号,如果不允许,则循环分组模型中的所有汽车并将其设置为false。反之亦然允许汽车。喜欢这段代码:
public class Cars
{
public string brand { get; set; }
public string model { get; set; }
public string allowed { get; set; }
}
var notAllowedModels = new HasSet<string>(GetNotAllowedModels()); // using hasset to improve the performance
foreach(var carGroup in cars.GroupBy(car => car.model)) // cars is a List<Car>
{
if (notAllowedModels.Contains(carGroup.Key))
foreach(var c in carGroup)
c.allowed = "No";
else
foreach(var c in carGroup)
c.allowed = "Yes";
}
Obs。:您应该在notAllowedModels中使用HasSet来提高代码的性能,因为Dictionary是索引的,而List不是,并且您每次都在循环中循环访问notAllowedCars。
答案 3 :(得分:0)
你可以进一步改进这个,但是下面的内容会有用吗?
foreach (var notAllowedCar in cars.Where((car) => notAllowedModels.Contains(car.model)))
{
notAllowedCar.allowed = "False";
}