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)
верно)?Если да, мы просто создаем его: extra ::: List(x)
это просто элементы extra
, за которыми следует один элемент x
.(Может быть лучше написать это как extra :+ x
- добавьте один элемент в конце.) Если нет, у нас есть только один элемент, но мы делаем его List(x)
вместо просто x
, потому что мы хотим всеиметь тот же тип.Так что теперь, если у нас есть что-то вроде
4 1 2 3 4
и наше условие заключается в том, что мы вставляем 5 6
перед 4
, мы генерируем
List(5 6 4) List(1) List(2) List(3) List(5 6 4)
Это именно то, что мы хотим,кроме того, у нас есть список списков.Чтобы избавиться от внутренних списков и объединить все в один список, мы просто вызываем flatten
.