Посмотрите на этот пример:
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:
(ответ переместился из этого дубликата )
Вот вариант, который является
Код:
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)
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)
Это можно сделать довольно чисто, используя sliding
:
myList.head :: myList.sliding(2).collect { case Seq(a,b) if a != b => b }.toList
Он смотрит на все пары, и для каждой пары несогласования (a,b)
он возвращает вас b
. Но тогда он должен придерживаться оригинала a
в начале списка.
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)
Конечно, вы можете сделать хвост рекурсивным
Я уверен, что есть лучший способ.
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)
просто удаляет индексы.
Попробуйте это,
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
Еще один вариант
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)
)