在数组上映射后调用排序
Calling sort after map on a array
我想在删除空格后按行长度对从 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."]
我不明白为什么。 map 函数不是应用于一个范围内的每个元素和 return 一个新范围吗?根据文档,sort
要求其范围参数是可随机访问的。是这个原因吗?如果是这样,由 map
编辑的范围 return 的类型是什么?
map
returns 一个没有可分配或可交换元素的范围 - sort
指定的另一个要求。与您的第一个示例一样,解决方案是首先迭代到一个数组。
元素不可赋值,因为 map
进行计算而不是 return 引用的值。因此,即使您确实获取了 returned 元素的地址,并用该位置的新值覆盖它,它也不会更改实际后备数组中的值。
问题其实比这个稍微严重一点。 [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
.
我想在删除空格后按行长度对从 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."]
我不明白为什么。 map 函数不是应用于一个范围内的每个元素和 return 一个新范围吗?根据文档,sort
要求其范围参数是可随机访问的。是这个原因吗?如果是这样,由 map
编辑的范围 return 的类型是什么?
map
returns 一个没有可分配或可交换元素的范围 - sort
指定的另一个要求。与您的第一个示例一样,解决方案是首先迭代到一个数组。
元素不可赋值,因为 map
进行计算而不是 return 引用的值。因此,即使您确实获取了 returned 元素的地址,并用该位置的新值覆盖它,它也不会更改实际后备数组中的值。
问题其实比这个稍微严重一点。 [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
.