2015-05-21 6 views

ответ

6

Вот один из способов сделать это:

Seq(1,2,3) flatMap { 
    case 1 => Seq(11) 
    case 2 => Seq(12,13,14) 
    case 3 => Seq(15) 
} 

res0: Seq [Int] = List (11, 12, 13, 14, 15)

+0

Вы действительно решили проблему OP? Мне кажется, этот список уже создан, и вы должны сгладить его, не так ли? –

+0

@DmitryGinzburg Я предполагаю, что OP понадобится сделать адаптацию для решения реальной проблемы, но мы не можем точно знать, что это такое. Это показывает, что вы можете сопоставить входы с 'Seq' и использовать 'flatMap' для решения этой проблемы. – Simon

0

Если у вас уже есть этот список, вы можете сделать flatMap для достижения требуемого результата:

val list = Seq(11, Seq(12, 13, 14), 15) 

val flattened = list.flatMap { 
    case x: Int => Seq(x) 
    case y: Seq[Int] => y 
} 

чтобы избежать предупреждений (хотя, это не поможет вам сделать этот код типобезопасный), вы можете использовать следующее:

val flattened = list.flatMap { 
    case x: Int => Seq(x) 
    case y: Seq[_] => y.asInstanceOf[Seq[Int]] 
} 
+0

Вы попробовали? Вы получите предупреждение о стирании стилей и получите Seq [Any], а не Seq [Int]. 'case y: Seq [_] => y' немного упростит, что информация о том, что находится в последовательности, потеряна (и избегает предупреждения). –

+0

@Paul Mmm, я получаю это предупреждение, тем не менее, тип 'flattened' -' Seq [Int] '. –

+0

Я не понимаю, как это может быть. Попробуйте 'val list = Seq (11, Seq (" s "," y "," x "), 15)', но не изменяйте свое определение 'flattened'. Он работает без ошибок, но определенно не возвращает 'Seq [Int]'! –

1

Вот еще один способ сделать это:

implicit def unitSeq[T](x: T): Seq[T] = Seq(x) 

Seq(1, 2, 3) flatMap { 
    case 1 => 11 
    case 2 => Seq(12, 13, 14) 
    case 3 => 15 
} 

res0: Seq [Int] = List (11, 12, 13, 14, 15)

1

Если у вас есть Seq(1,2,3) у вас есть Seq[Int] ,

после операции карты у вас есть проблемы, хотя

val mapped = Seq(1,2,3) map { 
    case 1 => 11 
    case 2 => Seq(12,13,14) 
    case 3 => 15 
} 

Что такое тип mapped? Разумным ответом на это может быть то, что у него нет типа. Это близко к истине. Получаемый тип: Seq[Any]. К сожалению, это совершенно бесполезный тип. Это не то, что вы могли бы сделать что-нибудь полезное с помощью метода типа, и можно было бы сделать хороший вывод о том, что Scala не должна допускать, чтобы этот тип был выведен в первую очередь.

Решение состоит в том, чтобы не допустить, чтобы это было далеко в первую очередь, но сопоставимо с тем, что имеет разумный тип. Решение показано Саймоном разумный подход:

val mapped = Seq(1,2,3) map { 
    case 1 => Seq(11) 
    case 2 => Seq(12,13,14) 
    case 3 => Seq(15) 
    case _ => throw new Exception("uh oh, didn't account for this to happen!") 
} 

Теперь отображается это Seq[Seq[Int]], и мы можем сделать более полезные вещи с ним, например, придавить его к Seq[Int] с mapped.flatten

Но мы можем получить там в один ход. Существует операция под названием flatMap по адресу Seq[A], которая принимает функцию A => Seq[A] как аргумент и возвращает один Seq[A].

val flatmapped = Seq(1,2,3) flatMap { 
    case 1 => Seq(11) 
    case 2 => Seq(12,13,14) 
    case 3 => Seq(15) 
    case _ => throw new Exception("uh oh, didn't account for this to happen!") 
} 

flatmapped теперь Seq(11, 12, 13, 14, 15)


Помимо

Оказывается, кстати, что это очень полезно иметь эту операцию на всех видах параметризованных типов: (F[A], A => F[A]) => F[A]

Например:

Option[A].flatMap(a: A => Option[A]): Option[A] 

def squareroot(x: Double): Option[Double] = if (x >= 0) Some(Math.sqrt(x)) 
              else None 

Some(4.0).flatMap(squareroot) == Some(2.0) 
Some(-1.0).flatMap(squareroot) == None 
None.flatMap(squareroot) == None 

или

Future[A].flatMap(a: A => Future[A]): Future[A] 

Эта операция иногда называют flatMap, а иногда называют bind, а иногда представлен в виде =>>, и если тип (назовем его F[A]), которые поддерживают эту операцию, и поддерживают еще одну операцию который может создать F[A] от A (иногда называется point, а иногда и называется return) и следуйте некоторым условиям, как эти операции составляют, F[A] формирует Monad

+0

'Скала не должна была допускать, чтобы этот тип был выведен в первую очередь. 'Вы получаете предупреждение об этом, хотя –

+0

По умолчанию? Я этого не знал, но это прогресс :) – Martijn

Смежные вопросы