Scala插入到特定位置的列表中 [英] Scala insert into list at specific locations
问题描述
这是我确实解决的问题,但是总的来说,这是Scala noob的必要条件,我觉得我发现了一些完全不优雅的东西。任何想法的改进赞赏。
val l1 = 4 :: 1 :: 2 :: 3 :: 4 :: Nil //原始列表
val插入=列表(88,99)//列表我想插入某些地方
//找到特定列表中特定元素的所有索引的方法
def indexesOf(元素:Any,inList:List [Any])= {
var index = List [Int]()
for(i < - 0 until inList.length){
if(inList (i)==元素)索引=索引:+ i
}
索引
}
var indexes = indexesOf(4,l1)/ /获得索引,其中4出现在原始列表中
println(索引)
var result = List [Any]()
// iterate (i < - 0,直到indices.length){
var prev = if(i == 0)0其他索引(i-1)
结果通过索引并插入前面
= result ::: l1.slice(prev,indexes(i))::: insert
}
result = result ::: l1.drop(indexes.last)//追加最后一位原始列表
pr intln(result)
我以为这样的东西可以实现更优雅的解决方案,但这只是纯粹的猜测。
var final:List [Any] =(0 /:indexes){(final,i)=> final ::: ins ::: l1.slice(i,indexes(i))
def insert [A](xs:List [A],extra:List [A])(p:A => Boolean)= {
xs.map(x => if(p(x))extra ::: List(x)else List(x))。flatten
}
scala> insert(List(4,1,2,3,4),List(88,99)){_ == 4}
res3:List [Int] = List(88,99,4,1,2 ,3,88,99,4)
编辑:添加了解释。
我们的目标是在所选元素的前面插入一个列表(称为 extra
)另一个列表(这里称为 xs
- 通常用于列表,就好像一件事是 x
那么很多列表必须是复数 xs
)。我们希望这可以在我们可能拥有的任何类型的列表上工作,所以我们用泛型类型 [A]
注释它。
哪些元素可供插入?在编写函数时,我们不知道,所以我们提供了一个函数,为每个元素指定true或false( p:A => Boolean
)。
现在,对于列表 x
中的每个元素,我们检查 - 我们是否应该插入(即 p(x)
true)?如果是,我们就构建它: extra ::: List(x)
就是 extra
的元素,后面跟着单个项目 x
。 (最好把它写成 extra:+ x
- 在最后添加单个项目。)如果不是,我们只有单个项目,但是我们会它 List(x)
而不是只是 x
,因为我们希望所有东西都具有相同的类型。所以,现在,如果我们有类似的东西,那么我们就可以用它来解决这个问题。
4 1 2 3 4
pre>
,我们的条件是我们在
4 $ c之前插入
5 6
$ c $>
$ $ p $列表(5 6 4)列表(1)列表(2)列表(3)列表( 5 6 4)
这正是我们想要的,除了我们有一个列表清单。为了摆脱内部列表并将所有东西平铺到一个列表中,我们只需调用 flatten
。
This is the problem that I did solve, however being a total imperative Scala noob, I feel I found something totally not elegant. Any ideas of improvement appreciated.
val l1 = 4 :: 1 :: 2 :: 3 :: 4 :: Nil // original list
val insert = List(88,99) // list I want to insert on certain places
// method that finds all indexes of a particular element in a particular list
def indexesOf(element:Any, inList:List[Any]) = {
var indexes = List[Int]()
for(i <- 0 until inList.length) {
if(inList(i) == element) indexes = indexes :+ i
}
indexes
}
var indexes = indexesOf(4, l1) // get indexes where 4 appears in the original list
println(indexes)
var result = List[Any]()
// iterate through indexes and insert in front
for(i <- 0 until indexes.length) {
var prev = if(i == 0) 0 else indexes(i-1)
result = result ::: l1.slice(prev, indexes(i)) ::: insert
}
result = result ::: l1.drop(indexes.last) // append the last bit from original list
println(result)
I was thinking more elegant solution would be achievable with something like this, but that's just pure speculation.
var final:List[Any] = (0 /: indexes) {(final, i) => final ::: ins ::: l1.slice(i, indexes(i))
def insert[A](xs: List[A], extra: List[A])(p: A => Boolean) = {
xs.map(x => if (p(x)) extra ::: List(x) else List(x)).flatten
}
scala> insert(List(4,1,2,3,4),List(88,99)){_ == 4}
res3: List[Int] = List(88, 99, 4, 1, 2, 3, 88, 99, 4)
Edit: explanation added.
Our goal here is to insert a list (called extra
) in front of selected elements in another list (here called xs
--commonly used for lists, as if one thing is x
then lots of them must be the plural xs
). We want this to work on any type of list we might have, so we annotate it with the generic type [A]
.
Which elements are candidates for insertion? When writing the function, we don't know, so we provide a function that says true or false for each element (p: A => Boolean
).
Now, for each element in the list x
, we check--should we make the insertion (i.e. is p(x)
true)? If yes, we just build it: extra ::: List(x)
is just the elements of extra
followed by the single item x
. (It might be better to write this as extra :+ x
--add the single item at the end.) If no, we have only the single item, but we make it List(x)
instead of just x
because we want everything to have the same type. So now, if we have something like
4 1 2 3 4
and our condition is that we insert 5 6
before 4
, we generate
List(5 6 4) List(1) List(2) List(3) List(5 6 4)
This is exactly what we want, except we have a list of lists. To get rid of the inner lists and flatten everything into a single list, we just call flatten
.
这篇关于Scala插入到特定位置的列表中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!