在修剪掉空白后,我想按行长对从stdin
读取的行进行排序。该代码按预期工作。
import std.algorithm, std.array, std.stdio, std.string;
void main()
{
stdin
.byLineCopy
.map!(strip)
.array
.sort!((a, b) => a.length < b.length)
.each!writeln;
}
但是,如果我将map
行换成array
行,则
void main()
{
stdin
.byLineCopy
.array
.map!(strip)
.sort!((a, b) => a.length < b.length)
.each!writeln;
}
程序无法编译,出现以下错误
sort_lines.d(9): Error: template std.algorithm.sorting.sort cannot deduce function from argument types !((a, b) => a.length < b.length)(MapResult!(strip, string[])), candidates are:
/usr/include/dmd/phobos/std/algorithm/sorting.d(1852): std.algorithm.sorting.sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r) if ((ss == SwapStrategy.unstable && (hasSwappableElements!Range || hasAssignableElements!Range) || ss != SwapStrategy.unstable && hasAssignableElements!Range) && isRandomAccessRange!Range && hasSlicing!Range && hasLength!Range)
Failed: ["/usr/bin/dmd", "-v", "-o-", "sort_lines.d", "-I."]
我不明白为什么。映射功能是否不适用于范围内的每个元素并返回新范围?根据文档,sort
要求其range参数是可随机访问的。是这个原因吗?如果是这样,map
返回的范围是什么类型?
答案 0 :(得分:2)
map
返回一个没有可分配或可交换元素的范围-sort
指定的另一个要求。与您的第一个示例一样,解决方案是首先迭代到数组。
元素不可分配,因为map
会进行计算并且不会通过ref返回值。因此,即使您确实抓取了返回元素的地址,并用该位置的新值覆盖了该地址,它也不会更改实际后备数组中的值。
问题实际上比这还糟。 [1,2,3].map!(a => a * 2)
所做的是将[1,2,3]中的一个元素乘以2。如果我做了类似[1,2,3].map!(a => a * 2)[0] = 4
的操作,则必须将函数a => a * 2
转换为找出要放入[1,2,3]的值,然后将其变成[2,2,3]。在上述情况下,这比较容易,但是如果我尝试分配5而不是4怎么办?如果映射函数是单向哈希怎么办?正如我们所看到的,唯一真正的解决方案是存储具有map
个ped值的商店,即[1,2,3].map.array
。