首页 > 解决方案 > 使用高阶函数在数组中创建重复元素

问题描述

这里是 D 语言的新手。我正在尝试使用高阶函数(即折叠!、减少!、过滤!、映射!)来创建数组元素的副本。我将我的通用函数声明为纯函数,并尝试以单行函数的形式完成此任务。到目前为止我最接近的是

auto dupList(T)(T[] list) pure { (return map!(a => a.repeat(2)); }

但这给了我以下输出

[[1,1],[2,2]]

而不是我真正想要的

[1, 1, 2, 2]

我这样调用函数

writeln(dupList(nums));

我没有使用 map,而是尝试使用 reduce 代替它,但是当我将 map 切换为 reduce 时,出现以下错误:

Error instantiated from here: `staticMap!(ReduceSeedType, __lambda2)` C:\D\dmd2\src\phobos\std\algorithm\iteration.d 3287
Error: template `D_Programs.duplist!int.duplist.__lambda2` cannot deduce function from argument types `!()(int, int)`, candidates are:  C:\D\dmd2\src\phobos\std\algorithm\iteration.d 3696
Error: template instance `D_Programs.duplist!int.duplist.F!(__lambda2)` error instantiating     C:\D\dmd2\src\phobos\std\meta.d 803
Error instantiated from here: `reduce!(int[])` D_Programs.d (refers to dupList)
Error `D_Programs.duplist!int.duplist.__lambda2` D_Programs.d (refers to dupList)
Error instantiated from here: `duplist!int` D_Programs.d (refers to where I'm calling from)

任何有关至少了解前三个错误以及我的功能哪里出错的帮助/建议将不胜感激。

标签: d

解决方案


map本质上用调用该元素上传递的函数的结果替换每个元素。由于您的函数返回一个包含两个ints 的数组,因此结果将是一个数组数组,每个元素包含两个ints。

有了这些知识,我们可以使用std.algorith.iteration.joiner

auto dupList(T)(T[] list) pure { return list.map!(a => a.repeat(2)).joiner; }

正如您所注意到的,它也应该可以使用reduce,但它有点复杂:

auto dupList(T)(T[] list) pure { return reduce!((a,b) => a~b~b)((T[]).init, list); }

比较复杂的原因是:

1)reduce的函数有两个参数 - 到目前为止归约的结果和下一个元素。

2)reduce假定传递数组的第一个元素是归约的起点,除非传递了种子值。由于第一个元素是 a T,而不是 a T[],我们需要传递一个种子值。[]不会,因为它的类型是void[],所以我们需要创建一个空的T[]. 这可以通过new T[0]或如上所述来完成(T[]).init

希望这会有所帮助 - 如果还有其他问题,请询问!:)


推荐阅读