Удаление последовательных дубликатов в списке и порядке сохраняющего элемента [Scala] [duplicate]

Посмотрите на этот пример:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope,$http) {

    var getJoke = function(){
        return $http.get('http://api.icndb.com/jokes/random').then(function(res){
            return res.data.value;  
        });
    }

    getJoke().then(function(res) {
        console.log(res.joke);
    });
});

Как вы можете видеть, getJoke возвращает разрешенное обещание (оно разрешено при возврате res.data.value). Таким образом, вы ждете, пока запрос $ http.get не будет завершен, а затем выполнится console.log (res.joke) (как обычный асинхронный поток).

Это plnkr:

http://embed.plnkr.co/XlNR7HpCaIhJxskMJfSg/

4
задан Mohamad Shiralizadeh 30 March 2015 в 06:00
поделиться

7 ответов

(ответ переместился из этого дубликата )

Вот вариант, который является

  • tail-recursive
  • не использует какие-либо методы из библиотеки (лучше или хуже)

Код:

def compress[A](xs: List[A]): List[A] = {
  @annotation.tailrec 
  def rec(rest: List[A], stack: List[A]): List[A] = {
    (rest, stack) match {
      case (Nil, s) => s
      case (h :: t, Nil) => rec(t, List(h))
      case (h :: t, a :: b) => 
        if (h == a) rec(t, stack) 
        else rec(t, h :: stack)
    }
  }
  rec(xs, Nil).reverse
}

Пример

println(compress(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e)))

создает следующий выход:

List('a, 'b, 'c, 'a, 'd, 'e)
1
ответ дан Andrey Tyukin 5 September 2018 в 07:54
поделиться
val myList = List(5, 7, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
  // > myList  : List[Int] = List(5, 7, 2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
myList.foldRight(List[Int]())((i: Int, right: List[Int]) => {
  if (right.isEmpty || right.head != i)
    i::right
  else
    right
}); // > res0: List[Int] = List(5, 7, 2, 3, 5, 3, 2)
1
ответ дан dexjq23 5 September 2018 в 07:54
поделиться

Это можно сделать довольно чисто, используя sliding:

myList.head :: myList.sliding(2).collect { case Seq(a,b) if a != b => b }.toList

Он смотрит на все пары, и для каждой пары несогласования (a,b) он возвращает вас b. Но тогда он должен придерживаться оригинала a в начале списка.

6
ответ дан dhg 5 September 2018 в 07:54
поделиться
val l = List(5, 7,2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)

def f(l: List[Int]): List[Int] = l match {
  case Nil => Nil
  case x :: y :: tail if x == y => f(y::tail)
  case x :: tail => x :: f(tail)
}

println(f(l)) //List(5, 7, 2, 3, 5, 3, 2)

Конечно, вы можете сделать хвост рекурсивным

1
ответ дан Marek Adamek 5 September 2018 в 07:54
поделиться

Один из способов:

Я уверен, что есть лучший способ.

list.tail.foldLeft(List[Int](list.head))((prev, next) => {
  if (prev.last != next) prev +: next
  else prev
})

foldLeft принимает параметр (в первом приложении) и переходит от слева направо по вашему списку, применяя prev и next к двум параметрам, которые она задана, где prev является результатом функции до сих пор, а next является следующим элементом в вашем списке.

другим способом:

list.zipWithIndex.filter(l => (l._2 == 0) || (l._1 != list(l._2-1))).map(_._1)

В общем случае list.zip(otherList) возвращает список кортежей соответствующих элементов. Например, List(1,2,3).zip(List(4,5,6)) приведет к List((1,4), (2,5), (3,6)). zipWithIndex - это конкретная функция, которая связывает каждый элемент списка с его индексом, в результате получается список, в котором каждый элемент имеет форму (original_list_element, index).

list.filter(function_returning_boolean) возвращает список только с возвращенными элементами true для function_returning_boolean. Функция, которую я дал, просто проверяет, равен ли этот элемент предыдущему в исходном списке (или индекс равен 0).

Последняя часть, .map(_._1) просто удаляет индексы.

4
ответ дан Ritwik Bose 5 September 2018 в 07:54
поделиться

Попробуйте это,

val y = list.sliding(2).toList

  val x =y.filter(x=> (x.head != x.tail.head)).map(_.head) :+ (y.reverse.filter(x=> x.head !=x.tail.head)).head.tail.head
0
ответ дан S.Karthik 5 September 2018 в 07:54
поделиться

Еще один вариант

val is = List(5, 7,2, 3, 3, 3, 5, 5, 3, 3, 2, 2, 2)
val ps = is.head::((is zip is.tail) collect { case (a,b) if a != b => b })
//> ps  : List[Int] = List(5, 7, 2, 3, 5, 3, 2)

(is zip is.tail делает что-то похожее на .sliding(2))

0
ответ дан The Archetypal Paul 5 September 2018 в 07:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: