Scala插入到特定位置的列表中 [英] Scala insert into list at specific locations

查看:121
本文介绍了Scala插入到特定位置的列表中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我确实解决的问题,但是总的来说,这是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 ,因为我们希望所有东西都具有相同的类型。所以,现在,如果我们有类似的东西,那么我们就可以用它来解决这个问题。

$ b

  4 1 2 3 4 
pre>

,我们的条件是我们在 4 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆