问题是,如何在Kotlin中创建类似迭代器的python。
考虑这个将字符串解析为子字符串的python代码:
def parse(strng, idx=1):
lst = []
for i, c in itermarks(strng, idx):
if c == '}':
lst.append(strng[idx:i-1])
break
elif c == '{':
sublst, idx = parse(strng, i+1)
lst.append(sublst)
else:
lst.append(strng[idx:i-1])
idx = i+1
return lst, i
>>>res,resl = parse('{ a=50 , b=75 , { e=70, f=80 } }')
>>>print(resl)
>>>[' a=50', ' b=75', [' e=7', ' f=80'], '', ' f=80']
这是一个播放示例,仅用于说明python迭代器:
def findany(strng, idx, chars):
""" to emulate 'findany' in kotlin """
while idx < len(strng) and strng[idx] not in chars:
idx += 1
return idx
def itermarks(strng, idx=0):
while True:
idx = findany(strng, idx, ',{}"')
if idx >= len(strng):
break
yield idx, strng[idx]
if strng[idx] == '}':
break
idx += 1
Kotlin有迭代器和生成器,据我所知,每种类型只能有一个。我的想法是定义一个带有生成器和类型实例的类型。所以来自'parse'(上面)的for循环看起来像这样:
for((i,c)in IterMarks(strng){ ...... }
但是我如何定义生成器,以及最好的习语是什么。
答案 0 :(得分:0)
Kotlin使用两个接口:Iterable<T>
(来自JDK)和Sequence<T>
。它们是相同的,除了第一个是急切的,而第二个是按惯例懒惰的。
要使用迭代器或序列,您只需实现其中一个接口即可。 Kotlin stdlib有一堆可能有帮助的辅助函数。
特别是1.1中添加了一些用yield
创建序列的函数。它们和其他一些函数称为generators
。如果您愿意,可以使用它们,或手动实现接口。
答案 1 :(得分:0)
好的,经过一些工作,这里是迭代器的Kotlin:
import kotlin.coroutines.experimental.*
fun iterMarks(strng: String, idx:Int=0)=buildSequence{
val specials = listOf("\"", "{", "}", ",")
var found:Pair<Int,String>?
var index = idx
while (true){
found = strng.findAnyOf(specials, index)
if (found == null) break
yield (found)
index= found.first + 1
}
}
主要发现是迭代器可以由任何函数返回,因此不需要将迭代器方法添加到现有对象。 JetBrains doco很稳固,但缺乏示例,所以希望上面的例子有所帮助。你也可以从基础工作,再次说明是好的,但缺乏例子。如果有兴趣,我会更多地介绍其他方法。
“解析”的代码可以起作用:
fun parse(strng:String, idxIn:Int=1): Pair<Any,Int> {
var lst:MutableList<Any> = mutableListOf()
var idx = idxIn
loop@ for (mark in iterMarks(strng, idx)){
if(mark==null ||mark.first <= idx){
// nothing needed
}
else
{
when( mark.second ) {
"}" -> {
lst.add(strng.slice(idx..mark.first - 1))
idx = mark.first + 1
break@loop
}
"{" -> {
val res: Pair<Any, Int>
res = parse(strng, mark.first + 1)
lst.add(res.first)
idx = res.second
}
"," -> {
lst.add(strng.slice(idx..mark.first - 1))
idx = mark.first + 1
}
}
}
}
return Pair(lst, idx)
}
希望通过提供实现迭代器的示例,这个示例将减少对Kotlin新手的下一个人的工作量。具体来说,如果你知道如何在python中创建一个迭代器,那么这个例子应该是有用的