LINQ转换函数

时间:2010-12-22 04:51:02

标签: c# linq

我只是一个奇怪的问题,linq中是否有任何转换功能。我的意思是,如果我有List<int>List<Foo>,我想更改索引x处的元素或满足条件的人。

2 个答案:

答案 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()