C# 等效于 Julia 的 map!() 方法
C# equivalent of Julia's map!() method
我正在尝试找到 C# 中与 Julia 的 map!()
方法等效的方法,该方法属于 void
return 类型并采用函数、目标和函数所在的集合行为。
我能找到的最好的东西是 C# 的 Enumerable.Select()
, which takes the function as the third argument, and the collection as the first argument. However, it returns a new collection instead of modifying the one in the "destination". That resembles Julia's map()
。
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 方法一样,这只有在目标集合至少一样大的情况下才有效。
没有像这样的标准,但您可以轻松地将自己的扩展方法添加到 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());
注意:我省略了任何错误处理。例如,您需要确保目标列表足够长以获取插入的值。
我正在尝试找到 C# 中与 Julia 的 map!()
方法等效的方法,该方法属于 void
return 类型并采用函数、目标和函数所在的集合行为。
我能找到的最好的东西是 C# 的 Enumerable.Select()
, which takes the function as the third argument, and the collection as the first argument. However, it returns a new collection instead of modifying the one in the "destination". That resembles Julia's map()
。
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 方法一样,这只有在目标集合至少一样大的情况下才有效。
没有像这样的标准,但您可以轻松地将自己的扩展方法添加到 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());
注意:我省略了任何错误处理。例如,您需要确保目标列表足够长以获取插入的值。