我想知道,如果有一个扩展方法允许我迭代List并让我对列表中的每个项目做同样的事情。例如:
.RemoveAll(x => x.property == somevalue)
这将删除满足条件的每个元素。但是,如果我有这个:
foreach(object item in lstObjects)
{
object MyObject = new object();
MyObject.propertyone = item.property
MyObject.propertytwo = somevalue;
anotherlist.Add(MyObject);
}
当然,真正的代码比这复杂一点。我的目标是,我找到foreach
而不是List<T>.ForEach()
使用扩展方法,但是我无法使用它,并且这个方法在var列表中不存在。我找到了.Select<>
,.Where<>
但是这会返回值,而在我的方法中则不需要返回任何值。
答案 0 :(得分:3)
var convertedItems = lstObjects.Select(item =>
{
object MyObject = new object();
MyObject.propertyone = item.property
MyObject.propertytwo = somevalue;
return MyObject;
});
anotherList.AddRange(convertedItems);
或
anotherList = convertedItems.ToList();
如果你想缩短它:
var convertedItems = lstObjects.Select(item =>
new object {propertyone = item.property, propertytwo = somevalue});
答案 1 :(得分:1)
我不确定我为什么要在这里找到扩展方法。 List<T>.ForEach()
会主要执行您喜欢的操作,但您现有的foreach
循环既是惯用的又是可读的。有没有理由你不能只写一个正常的函数来做这个?
public void DoMyThing(IList<object> objects) {
foreach (var obj in objects) {
someOtherList.Add(new MyObj() {
item1 = obj
});
}
}
通常,如果您发现需要改变项而不返回值,则不希望使用LINQ或查询运算符。只需使用foreach
。
编辑:建议Select()
的答案适用于这个简单的代码,但是你声明了
实际代码比这个更复杂
对我来说,你可能不得不在迭代期间改变其他状态。 Select
方法将推迟此突变,直到序列实现为止;除非您熟悉LINQ查询如何延迟执行并捕获外部变量,否则这可能会给您带来奇怪的结果。
答案 2 :(得分:0)
编写自己的ForEach扩展程序是微不足道的。我在所有代码中都包含以下内容:
public static void ForEach<T>(this IEnumerable<T> collection, Action<T> action )
{
foreach (T item in collection)
{
action(item);
}
}
答案 3 :(得分:0)
您可以通过Select语句完成此操作:
var newList = lstObjects.Select(o =>
new { propertyone = o.property,
propertytwo = somevalue }).ToList();
答案 4 :(得分:0)
以下是ForEach
与lambda表达式的对比方式:
lstObjects.ForEach(item =>
{
MyObject obj = new MyObject();
obj.propertyone = item.property;
obj.propertytwo = somevalue;
anotherlist.Add(obj);
});
然而,你可以看到它看起来与你已经拥有的非常相似!
另外,我认为Select
可能更适合您想做的事情:
anotherList.AddRange(lstObjects.Select(item => new MyObject()
{
propertyone = item.property,
obj.propertytwo = somevalue,
}));
答案 5 :(得分:0)
List<MyObjectType> list = new List<MyObjectType>();
list.ForEach((MyObjectType item) => {
object MyObject = new object()
{
MyObject.propertyone = item.property,
MyObject.propertytwo = somevalue
};
anotherlist.Add(MyObject);
});
答案 6 :(得分:0)
如果要在迭代过程中执行操作,可能需要考虑作为Interactive Extensions一部分的.Do方法。见http://www.thinqlinq.com/Post.aspx/Title/Ix-Interactive-Extensions-return。
答案 7 :(得分:0)
您可以轻松创建扩展方法来执行此操作:
public IEnumerable<T> RemoveAll(this List<T> list, Func<bool, T> condition)
{
var itemsToRemove = list.Where(s => condition(s));
list.RemoveAll(itemsToRemove);
}
然后你就可以这样称呼它:
myList.RemoveAll(x => x.Property == someValue);
编辑:这是another method执行相同操作。
答案 8 :(得分:0)
就“内置”而言,没有.ForEach()
;但是我觉得.Aggregate()
在这里是最合适的选择(如果你绝对想要一个内置函数)。
lstObjects.Aggregate(anotherList, (targetList, value) =>
{
object MyObject = new object();
MyObject.propertyone = item.property
MyObject.propertytwo = somevalue;
targetList.Add(MyObject);
return targetList;
});
您显然可以编写自己的扩展方法:
public static IEnumerable<T> Intercept<T>(this IEnumerable<T> values, Action<T> each)
{
foreach (var item in values)
{
each(item);
yield return item;
}
}
public static IEnumerable<T> Intercept<T>(this IEnumerable<T> values, Action<T, int> each)
{
var index = 0;
foreach (var item in values)
{
each(item, index++);
yield return item;
}
}
// ...
a.Intercept(x => { Console.WriteLine(x); }).Count();
NB:我不像其他人一样创建ForEach的原因是因为Microsoft没有包含它,因为按照设计Linq方法总是返回一个值或值列表。 / p>
特别针对您的问题,.Select<T>
可以解决问题。
anotherList.AddRange(lstObjects.Select(x => new MyObject()
{
propertyone = x.property,
propertytwo = somevalue
}));