【发布时间】:2014-07-21 20:57:05
【问题描述】:
是否有 Scala 库 API 方法(如果没有,则为惯用方式)来获取较大字符串(源)中子字符串(目标)的所有索引的列表?我试图浏览 ScalaDoc,但找不到任何明显的东西。有这么多方法可以做这么多有用的事情,我猜我只是没有提交正确的搜索词。
例如,如果我有一个源字符串“name:Yo,name:Jim,name:name,name:bozo”,而我使用目标字符串“name:”,我想返回一个 List List(0, 8, 17, 27) 的 [Int]。
这是我解决问题的快速技巧:
def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = {
def recursive(index: Int, accumulator: List[Int]): List[Int] = {
if (!(index < source.size)) accumulator
else {
val position = source.indexOf(target, index)
if (position == -1) accumulator
else {
recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator)
}
}
}
if (target.size <= source.size) {
if (!source.equals(target)) {
recursive(0, Nil).reverse
}
else List(0)
}
else Nil
}
您能给我的任何指导都将其替换为适当的标准库入口点,我们将不胜感激。
2019 年 6 月 16 日更新:
进一步收紧代码:
def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = {
def recursive(indexTarget: Int = index, accumulator: List[Int] = Nil): List[Int] = {
val position = source.indexOf(target, indexTarget)
if (position == -1)
accumulator
else
recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator)
}
recursive().reverse
}
2014 年 7 月 22 日更新:
受 Siddhartha Dutta 的回答启发,我收紧了我的代码。现在看起来像这样:
def indexesOf(source: String, target: String, index: Int = 0, withinOverlaps: Boolean = false): List[Int] = {
@tailrec def recursive(indexTarget: Int, accumulator: List[Int]): List[Int] = {
val position = source.indexOf(target, indexTarget)
if (position == -1) accumulator
else
recursive(position + (if (withinOverlaps) 1 else target.size), position :: accumulator)
}
recursive(index, Nil).reverse
}
另外,如果我有一个源字符串“aaaaaaaa”并且我使用一个目标字符串“aa”,我希望默认返回 List(0, 2, 4, 6) 的 List[Int]它跳过从找到的子字符串内部开始的搜索。可以通过为 insideOverlaps 参数传递“true”来覆盖默认值,在“aaaaaaaa”/“aa”的情况下,该参数将返回 List(0, 1, 2, 3, 4, 5, 6)。
【问题讨论】:
-
不,没有“[标准]方法”。此外,由于这是工作代码,它可能更适合代码审查。
-
@chaotic3quilibrium 任何方式你可以 BSD 许可该方法,这样如果我复制/改编它,老板就不会生我的气? :)
-
@ericpeters 我的理解是,在 StackOverflow 上发布的任何 sn-ps 代码都可能被假定为本质上是公共领域;即不受任何许可限制的限制,限制您将 sn-p 剪切/粘贴/修改/自定义到您需要的任何上下文的能力。
-
@chaotic3quilibrium 这是一个有趣的灰色地带,从技术上讲,他们直到 3 月才成为 MIT-ish 归因 (meta.stackexchange.com/questions/271080/…)
-
您应该更新答案以使用 Vector(并附加而不是 prepend)而不是 List 以避免最后的额外 .reverse 。可能也有助于返回类型 IndexedSeq[Int]