foreach - 可变参数的解构迭代,如 D 中的元组序列
问题描述
假设我想处理一个可变参数函数,该函数交替传递 1 个或多个间隔的开始值和结束值,并且它应该在这些间隔中返回一系列随机值。你可以想象输入是一个扁平的元组序列,所有元组元素都分布在一个范围内。
import std.meta; //variadic template predicates
import std.traits : isFloatingPoint;
import std.range;
auto randomIntervals(T = U[0], U...)(U intervals)
if (U.length/2 > 0 && isFloatingPoint!T && NoDuplicates!U.length == 1) {
import std.random : uniform01;
T[U.length/2] randomValues;
// split and iterate over subranges of size 2
foreach(i, T start, T end; intervals.chunks(2)) { //= intervals.slide(2,2)
randomValues[i] = uniform01 * (end - start) + start,
}
return randomValues.dup;
}
例子不重要,我只是用来解释。块大小可以是任何有限的正数size_t
,不仅2
并且更改块大小只需要更改 foreach 循环中的循环变量的数量。
在上面的这种形式中,它不会编译,因为它只期望 foreach 循环有一个参数(一个范围)。我想要的是自动使用或推断滑动窗口作为元组的东西,从给定循环变量的数量派生,并用范围/数组的下一个元素填充附加变量+允许附加索引,可选。根据文档,元组范围允许将元组元素解构为foreach -loop-variables,因此我想到的第一件事是将范围转换为元组序列,但没有找到方便的功能为了这。
有没有一种简单的方法可以将解构的子范围(如我的示例代码中所示的简单)与索引一起循环?或者是否有一个(标准库)函数可以将范围拆分为相同大小的枚举元组?如何轻松地将子范围的范围变成元组的范围?
在这种情况下是否有可能std.algorithm.iteration.map
(编辑:使用简单的函数参数来映射并且不访问元组元素)?
编辑:我想忽略不适合整个元组的最后一个块。它只是没有迭代。
编辑:这不是我自己无法编程,我只希望有一个简单的符号,因为这种循环多个元素的用例非常有用。如果在 D 中有类似 JavaScript 中的“spread”或“rest”运算符,请告诉我!
谢谢你。
解决方案
chunks
并slide
返回Range
s,而不是元组。它们的最后一个元素可以包含小于指定大小,而元组具有固定的编译时间大小。
如果您需要解构,则必须实现自己的返回元组的块/幻灯片。要向元组显式添加索引,请使用enumerate
. 这是一个例子:
import std.typecons, std.stdio, std.range;
Tuple!(int, int)[] pairs(){
return [
tuple(1, 3),
tuple(2, 4),
tuple(3, 5)
];
}
void main(){
foreach(size_t i, int start, int end; pairs.enumerate){
writeln(i, ' ', start, ' ', end);
}
}
编辑:
正如 BioTronic 所说,使用map
也是可能的:
foreach(i, start, end; intervals
.chunks(2)
.map!(a => tuple(a[0], a[1]))
.enumerate){
推荐阅读
- r - 从数据表中删除具有特定字符串的行
- c# - visual studio winforms 无法使用移动图标移动
- python - 从两个列表中插入值 - ValueError:要解包的值太多(预期为 2)
- javascript - TypeError:无法从 Fetch 调用中读取未定义的嵌套 Json 的属性“fixtures”
- loops - Cplex:如何在 for 循环中从 dat.file 读取不同的数据输入
- java - Java SonarQube 错误“使公共静态字段最终化”
- c# - WPF:如何画一个圆?
- docker-compose - 看不到 Consul UI
- firebase - 我可以在 Firebase 身份验证中将身份验证提供商从谷歌帐户更改为匿名吗?
- ios - 空的手机号码在iOS中可以调用吗?