我试图找到与Julia的map!()
方法等效的C#方法,该方法的返回类型为void
,并采用一个函数,一个目的地和一个函数作用于其上的集合。
我能找到的最好的东西是C#的Enumerable.Select()
,它将函数作为第三个参数,并将集合作为第一个参数。但是,它返回一个新集合,而不是修改“目标”中的集合。类似于Julia的map()
。
答案 0 :(得分:2)
没有像这样的标准,但是您可以轻松地将自己的扩展方法添加到IEnumerable
中以添加此功能。例如:
public static void JuliaMap<TFrom, TTo>
(
this IEnumerable<TFrom> source,
IList<TTo> target,
Func<TFrom, TTo> selector
)
{
var next = 0;
foreach(var value in source)
{
var convertedValue = selector(value);
target[next] = convertedValue;
next++;
}
}
怎么说:
var numbers = new[]{1, 2, 3};
var target = new string[3];
numbers.JuliaMap(target, i => (i * 2).ToString());
注意:我没有进行任何错误处理。例如,您需要确保目标列表足够长以接受插入的值。
答案 1 :(得分:1)
LINQ
中的所有内容都是设计使然,永远不要修改基础集合,并且总是创建一个新的枚举,然后通常将其用于实例化新的集合。
您可以编写这样的辅助函数来实现所需的功能:
public static void SelectToDestination<TSource, TResult>(
Func<TSource, TResult> selector,
IEnumerable<TSource> source,
IList<TResult> destination)
{
int i = 0;
foreach (var item in source.Select(selector))
{
destination[i] = item;
i++;
}
}
用法如下:
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new List<int>() { 0, 0, 0, 0 };
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
结果:3 4 5 6
由于我们在方法的签名中使用了IList<T>
,所以目标也可以是数组,并且可以正常工作:
public static void Main(string[] args)
{
var l1 = new List<int>() { 1, 2, 3, 4 };
var l2 = new int[4];
SelectToDestination(x => x + 2, l1, l2);
foreach(var item in l2)
{
Console.Write(item + " ");
}
}
它利用了以下事实:在您调用类似ToArray()
或ToList()
之类的东西之前,LINQ尚未实例化新的集合,它只是懒惰地遍历源集合中的元素。因此,只需不调用ToArray()
或ToList()
,就对生成的IEnumerable<TResult>
进行迭代并将其分配给目的地。请注意,如果您对此感到担心,则可能有其他更友好的方式来执行此操作。
就像Julia的map方法一样,只有在目标集合至少一样大的情况下,此方法才起作用。