Scala - 从单个字符串中删除 list/map 个字符串中的所有元素
Scala - Remove all elements in a list/map of strings from a single String
在内部网站上工作,其中 URL 包含来自其他系统的源引用。这是业务要求,无法更改。
即“http://localhost:9000/source.address.com/7808/project/repo”
“http://localhost:9000/build.address.com/17808/project/repo”
我需要使用特征从 "project/repo" string/variables 中删除这些字符串,以便可以在多个服务中本地使用。我还希望能够向这个列表(已经存在)添加更多源并且不修改方法。
"def normalizePath"是服务访问的方法,目前2次不理想但合理的尝试。卡在使用 foldLeft 上,我希望得到一些帮助或更简单的方法来完成所描述的。下面的代码示例。
第一次尝试使用 if-else(不理想,因为需要添加更多 if/else 语句,而且可读性不如模式匹配)
trait NormalizePath {
def normalizePath(path: String): String = {
if (path.startsWith("build.address.com/17808")) {
path.substring("build.address.com/17808".length, path.length)
} else {
path
}
}
}
和第二次尝试(不理想,因为可能会添加更多模式,并且它生成的字节码比 if/else 多)
trait NormalizePath {
val pattern = "build.address.com/17808/"
val pattern2 = "source.address.com/7808/"
def normalizePath(path: String) = path match {
case s if s.startsWith(pattern) => s.substring(pattern.length, s.length)
case s if s.startsWith(pattern2) => s.substring(pattern2.length, s.length)
case _ => path
}
}
最后一次尝试是使用地址列表(已经存在于其他地方但在此处定义为 MWE)从路径字符串中删除匹配项,但它不起作用:
trait NormalizePath {
val replacements = (
"build.address.com/17808",
"source.address.com/7808/")
private def remove(path: String, string: String) = {
path-string
}
def normalizePath(path: String): String = {
replacements.foldLeft(path)(remove)
}
}
感谢对此的任何帮助!
一个非常简单的替换可以如下:
val replacements = Seq(
"build.address.com/17808",
"source.address.com/7808/")
def normalizePath(path: String): String = {
replacements.find(path.startsWith(_)) // find the first occurrence
.map(prefix => path.substring(prefix.length)) // remove the prefix
.getOrElse(path) // if not found, return the original string
}
由于预期的替换非常相似,您是否尝试过概括它们并使用正则表达式匹配?
如果您只是删除这些字符串:
val replacements = Seq(
"build.address.com/17808",
"source.address.com/7808/")
replacements.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
case(path, toReplace) => path.replaceAll(toReplace, "")
}
// http://localhost:9000/project/repo
如果您要用其他内容替换这些字符串:
val replacementsMap = Seq(
"build.address.com/17808" -> "one",
"source.address.com/7808/" -> "two/")
replacementsMap.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
case(path, (toReplace, replacement)) => path.replaceAll(toReplace, replacement)
}
// http://localhost:9000/two/project/repo
replacements
集合可以来自代码中的其他地方,不需要重新部署。
// method replacing by empty string
def normalizePath(path: String) = {
replacements.foldLeft(path){
case(startingPoint, toReplace) => startingPoint.replaceAll(toReplace, "")
}
}
normalizePath("foobar/build.address.com/17808/project/repo")
// foobar/project/repo
normalizePath("whateverPath")
// whateverPath
normalizePath("build.address.com/17808build.address.com/17808/project/repo")
// /project/repo
在 Scala 中有一百万零一种从字符串中提取 /project/repo
的方法。以下是我想出的一些:
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
path.stripPrefix(list.find(x => path.contains(x)).getOrElse(""))
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
list.map(x => if (path.contains(x)) {
path.takeRight(path.length - x.length)
}).filter(y => y != ()).head
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: Any = /project/repo
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
list.foldLeft(path)((a, b) => a.replace(b, ""))
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo
实际上,这取决于您希望代码看起来多复杂(或者您希望代码看起来多傻)。请注意,第二个示例具有 return 类型 Any
,这可能不适合您的方案。此外,这些示例并不意味着只能从 path
的中间取出字符串...如果您想这样做,可以很容易地修改它们。如果您想让我添加一些示例,让我知道只是从字符串中剥离 build.address.com/17808
之类的东西 - 我很乐意这样做。
在内部网站上工作,其中 URL 包含来自其他系统的源引用。这是业务要求,无法更改。 即“http://localhost:9000/source.address.com/7808/project/repo” “http://localhost:9000/build.address.com/17808/project/repo”
我需要使用特征从 "project/repo" string/variables 中删除这些字符串,以便可以在多个服务中本地使用。我还希望能够向这个列表(已经存在)添加更多源并且不修改方法。
"def normalizePath"是服务访问的方法,目前2次不理想但合理的尝试。卡在使用 foldLeft 上,我希望得到一些帮助或更简单的方法来完成所描述的。下面的代码示例。
第一次尝试使用 if-else(不理想,因为需要添加更多 if/else 语句,而且可读性不如模式匹配)
trait NormalizePath {
def normalizePath(path: String): String = {
if (path.startsWith("build.address.com/17808")) {
path.substring("build.address.com/17808".length, path.length)
} else {
path
}
}
}
和第二次尝试(不理想,因为可能会添加更多模式,并且它生成的字节码比 if/else 多)
trait NormalizePath {
val pattern = "build.address.com/17808/"
val pattern2 = "source.address.com/7808/"
def normalizePath(path: String) = path match {
case s if s.startsWith(pattern) => s.substring(pattern.length, s.length)
case s if s.startsWith(pattern2) => s.substring(pattern2.length, s.length)
case _ => path
}
}
最后一次尝试是使用地址列表(已经存在于其他地方但在此处定义为 MWE)从路径字符串中删除匹配项,但它不起作用:
trait NormalizePath {
val replacements = (
"build.address.com/17808",
"source.address.com/7808/")
private def remove(path: String, string: String) = {
path-string
}
def normalizePath(path: String): String = {
replacements.foldLeft(path)(remove)
}
}
感谢对此的任何帮助!
一个非常简单的替换可以如下:
val replacements = Seq(
"build.address.com/17808",
"source.address.com/7808/")
def normalizePath(path: String): String = {
replacements.find(path.startsWith(_)) // find the first occurrence
.map(prefix => path.substring(prefix.length)) // remove the prefix
.getOrElse(path) // if not found, return the original string
}
由于预期的替换非常相似,您是否尝试过概括它们并使用正则表达式匹配?
如果您只是删除这些字符串:
val replacements = Seq(
"build.address.com/17808",
"source.address.com/7808/")
replacements.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
case(path, toReplace) => path.replaceAll(toReplace, "")
}
// http://localhost:9000/project/repo
如果您要用其他内容替换这些字符串:
val replacementsMap = Seq(
"build.address.com/17808" -> "one",
"source.address.com/7808/" -> "two/")
replacementsMap.foldLeft("http://localhost:9000/source.address.com/7808/project/repo"){
case(path, (toReplace, replacement)) => path.replaceAll(toReplace, replacement)
}
// http://localhost:9000/two/project/repo
replacements
集合可以来自代码中的其他地方,不需要重新部署。
// method replacing by empty string
def normalizePath(path: String) = {
replacements.foldLeft(path){
case(startingPoint, toReplace) => startingPoint.replaceAll(toReplace, "")
}
}
normalizePath("foobar/build.address.com/17808/project/repo")
// foobar/project/repo
normalizePath("whateverPath")
// whateverPath
normalizePath("build.address.com/17808build.address.com/17808/project/repo")
// /project/repo
在 Scala 中有一百万零一种从字符串中提取 /project/repo
的方法。以下是我想出的一些:
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
path.stripPrefix(list.find(x => path.contains(x)).getOrElse(""))
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
list.map(x => if (path.contains(x)) {
path.takeRight(path.length - x.length)
}).filter(y => y != ()).head
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: Any = /project/repo
val list = List("build.address.com/17808", "source.address.com/7808") //etc
def normalizePath(path: String) = {
list.foldLeft(path)((a, b) => a.replace(b, ""))
}
输出:
scala> normalizePath("build.address.com/17808/project/repo")
res0: String = /project/repo
实际上,这取决于您希望代码看起来多复杂(或者您希望代码看起来多傻)。请注意,第二个示例具有 return 类型 Any
,这可能不适合您的方案。此外,这些示例并不意味着只能从 path
的中间取出字符串...如果您想这样做,可以很容易地修改它们。如果您想让我添加一些示例,让我知道只是从字符串中剥离 build.address.com/17808
之类的东西 - 我很乐意这样做。