从List添加和删除元素的方法

时间:2014-10-10 13:47:16

标签: list scala collections

我正在编写一个方法,该方法采用list: List[(String, Int)]x:(String, Int)n: Int个参数并返回List [(String,Int)] list参数表示输入列表,x元素表示要添加到列表的元素,n表示列表的最大维度。

该方法具有以下行为:

  1. 首先检查列表是否包含n元素。
  2. 如果list有     少于n个元素,该方法会将x元素添加到列表中。
  3. 否则,如果列表包含小于x的元素,则为     方法从列表中删除最小元素,并添加x     元素到列表。
  4. 我已按如下方式实施该方法:

    def method(list: List[(String, Int)], x: (String, Int), n: Int) = {
                if(list.size < n)
                    list :+ x
                else {
                   var index = -1
                   var min = 10000000//some big number
                   for(el <- 0 to list.size) {
                     if(list(el)._2 < x._2 && list(el)._2 < min) {
                        min = list(el)._2
                        index = el
                      }
                   } 
                   if(index != -1) {
                       val newList = list.drop(index)
                       newList :+ x
                   }
                   else list
    
    
                  }
    
    
            }
    

    是否存在以更干净的方式表达此行为的方法?

2 个答案:

答案 0 :(得分:1)

首先,您发布的内容的更正版本(但看起来,而不是您的意图)

def method(list: List[(String, Int)], x: (String, Int), n: Int) = {
    if(list.size < n)
        list :+ x
    else {
       var index = -1
       for(i <- 0 until list.size) {
         val el = list(i)
          if(el._2 < x._2)
            index = i
       }
       if(index != -1) {
           val (before, after) = list.splitAt(index)
           val newList = before ++ after.tail
           newList :+ x
       }
       else list
      }
}   

还有一些测试

val l1 = List(("one", 1))            

val l2 = method(l1, ("three", 3), 2)
//> l2  : List[(String, Int)] = List((one,1), (three,3))
val l3 = method(l2, ("four", 4), 2)
//> l3  : List[(String, Int)] = List((one,1), (four,4))
val l4 = method(l2, ("zero", 0), 2)
//> l4  : List[(String, Int)] = List((one,1), (three,3))

Neater版本(但仍不符合OP评论中提到的规范)

 def method(list: List[(String, Int)], x: (String, Int), n: Int) = {
    if (list.size < n)
      list :+ x
    else {
      val (before, after) = list.span(_._2 >= x._2)
      if (after.isEmpty)
        list
      else
        before ++ after.tail :+ x
    }
  } 

另一个版本总是删除最小值,如果小于x。

 def method(list: List[(String, Int)], x: (String, Int), n: Int) = {
    if (list.size < n)
      list :+ x
    else {
      val smallest = list.minBy(_._2)
      if (smallest._2 < x._2) {
        val (before, after) = list.span(_ != smallest)
        before ++ after.tail :+ x
      } else
        list
    }
  }

及其测试结果

val l1 = List(("one", 1))


val l2 = method(l1, ("three", 3), 2) 
//> l2  : List[(String, Int)] = List((one,1), (three,3))
val l3 = method(l2, ("four", 4), 2) 
//> l3  : List[(String, Int)] = List((three,3), (four,4))
val l4 = method(l2, ("zero", 0), 2)
//> l4  : List[(String, Int)] = List((one,1), (three,3))

但正如我在评论中所说,最好使用一种方法来处理整个X序列并返回前N个。

答案 1 :(得分:-1)

我会将方法与方法本身分开:

def method[A: Ordering](list: List[A], x: A, n: Int) = ...

如果列表包含多个小于x的元素,您想要做什么?如果您对替换所有这些内容感到满意,可以使用map而不是手写循环:

list map {
    case a if Ordering.lt(a, x) => x
    case a => a
}

如果您只想替换列表中的最小元素,那么使用min可能更简洁吗?

val m = list.min
if(m < x) {
  val (init, m :: tail) = list.splitAt(list.indexOf(m))
  init ::: x :: tail
else list