C#相当于Julia的map!()方法

时间:2020-07-17 11:52:10

标签: c# julia equivalent

我试图找到与Julia的map!()方法等效的C#方法,该方法的返回类型为void,并采用一个函数,一个目的地和一个函数作用于其上的集合。

我能找到的最好的东西是C#的Enumerable.Select(),它将函数作为第三个参数,并将集合作为第一个参数。但是,它返回一个新集合,而不是修改“目标”中的集合。类似于Julia的map()

2 个答案:

答案 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方法一样,只有在目标集合至少一样大的情况下,此方法才起作用。