我只是一个奇怪的问题,linq中是否有任何转换功能。我的意思是,如果我有List<int>
或List<Foo>
,我想更改索引x处的元素或满足条件的人。
答案 0 :(得分:11)
如果您希望有条件地将Foo投射到另一个Foo(让其他人保持不变),您可以执行以下操作:
IEnumerable<Foo> foos = ...
var transformed = foos.Select(foo => myCondition(foo) ? transform(foo) : foo);
另一方面,如果您只想投影符合条件的Foos:
var transformed = foos.Where(foo => myCondition(foo))
.Select(foo => transform(foo));
请注意,这两个都返回 new 序列 - LINQ通常不用于修改现有集合。当然,您可以将结果具体化为集合,并在必要时覆盖现有变量。
// assuming the transform is from Foo -> Foo
foos = foos.Select(foo => transform(foo)).ToList();
由于您特别提到列表,因此第一个查询还有另一个非LINQ立即执行替代方法 - List<T>.ConvertAll
方法:
List<Foo> foos = ...
// implicitly List<Foo> assuming the transform is from Foo -> Foo
var transformed = foos.ConvertAll
(foo => myCondition(foo) ? transform(foo) : foo);
编辑:听起来你正在寻找一个“ReplaceWhere”方法 - 据我所知,没有直接框架方法取代了基于谓词的列表。不过你自己写一个很容易:
/// <summary>
/// Replaces items in a list that match the specified predicate,
/// based on the specified selector.
/// </summary>
public static void ReplaceWhere<T>(this IList<T> list,
Func<T, bool> predicate,
Func<T, T> selector)
{
// null-checks here.
for (int i = 0; i < list.Count; i++)
{
T item = list[i];
if (predicate(item))
list[i] = selector(item);
}
}
<强>用法强>:
List<int> myList = ...
myList.ReplaceWhere(i => i > 0, i => i * i);
答案 1 :(得分:4)
你当然可以写一个转换函数:
// allows you to transform every element
public static List<T> TransformAll<T>(this List<T> list,
Func<T, T> converter)
{
for (int i = 0; i < list.Count; i++)
{
list[i] = converter(list[i]);
}
return list;
}
// allows you to transform every element based on its index
public static List<T> TransformAll<T>(this List<T> list,
Func<T, int, T> converter)
{
for (int i = 0; i < list.Count; i++)
{
list[i] = converter(list[i], i);
}
return list;
}
// allows you to transform chosen elements
public static List<T> TransformWhere<T>(this List<T> list,
Func<T, bool> predicate,
Func<T, T> converter)
{
for (int i = 0; i < list.Count; i++)
{
T item = list[i];
if (predicate(item))
list[i] = converter(item);
}
return list;
}
// allows you to transform chosen elements based on its index
public static List<T> TransformWhere<T>(this List<T> list,
Func<T, int, bool> predicate,
Func<T, int, T> converter)
{
for (int i = 0; i < list.Count; i++)
{
T item = list[i];
if (predicate(item, i))
list[i] = converter(item, i);
}
return list;
}
请注意,我让所有函数都返回传入列表,以便您可以流畅地使用它们,例如list.TransformAll(x => x + 2).Sum()
。