我想按递减顺序迭代一个整数序列,但我找不到内置的方法。我是在数组索引的上下文中这样做的,但这个概念当然是通用的。
Ballerina有一个范围表达式,但只能用于增量迭代:
范围expr的结果是属于该对象的新对象type Iterable<int,((>将在中的整数序列上迭代增加订单〔…〕
所以这正如预期的那样工作:
public function main() {
final string[] x = ["A","B","C","D"];
foreach int i in 0 ..< x.length() {
io:print(x[i]);
}
io:println();
}
// prints: ABCD
但由于x.length()-1
大于0
(但它编译时没有问题(,以下内容没有(即它什么都不打印(:
public function main() {
final string[] x = ["A","B","C","D"];
foreach int i in x.length()-1 ... 0 {
io:print(x[i]);
}
io:println();
}
我目前的工作是生成索引,并分两个不同的步骤使用它们,例如:
public function main() {
final string[] x = ["A","B","C","D"];
final int[] indexes = from int i in 0 ..< x.length() order by i descending select i;
foreach int i in indexes {
io:print(x[i]);
}
io:println();
}
// prints: DCBA
但与范围表达相比,这感觉很笨拙。我们也放松了范围表达式的(假定的(惰性,对吧?
文档中说范围表达式的返回类型是:
属于对象类型
Iterable<int,()>
的新对象
这和关于Iterable的文档暗示,可以实现这样的对象,但我不知道如何实现。
或者还有其他方法可以按递减顺序迭代整数的范围/序列吗?
我正在使用:
$ bal version
Ballerina 2201.1.0 (Swan Lake Update 1)
Language specification 2022R2
Update Tool 1.3.9
到目前为止,还没有直接的方法来实现这一点。但它在计划中。有一个规范问题要跟踪。
作为替代方案,您可以编写迭代器(对象的实现:Iterable接口(。但这看起来可能是一个漫长的过程。以下示例从20递减到10。
import ballerina/io;
public class Decrementor {
private int startVal;
private int endVal;
private int i;
public function init(int startVal, int endVal) {
self.startVal = startVal;
self.endVal = endVal;
self.i = startVal;
}
public function next() returns record {|int value;|}? {
if self.i < self.endVal {
return ();
}
int val = self.i;
self.i -= 1;
return {value: val};
}
}
class Iterator {
*object:Iterable;
public function iterator() returns Decrementor {
return new Decrementor(20, 10);
}
}
public function main() {
foreach any|error i in new Iterator() {
io:println(i);
}
}
import ballerina/io;
public function main() {
final string[] x = ["A","B","C","D"];
// Method 1
foreach string i in x.reverse() {
io:println(i); // DCBA
}
io:println(x); // ["A","B","C","D"]
// Method 2
foreach int i in -(x.length()-1) ... 0 {
io:println(x[-i]); // DCBA
}
}