2009-07-16 4 views

ответ

21

Непонятно, о чем вы просите - что вы ожидаете от семантики множественного урожая. Одно дело, однако, в том, что вы, вероятно, никогда не захотите использовать индексы для навигации по списку - каждый вызов t (i) выполняется O (i).

Так вот одна возможность, что вы могли бы просить

scala> val l = List(1,2,3); val t = List(-1,-2,-3) 
l: List[Int] = List(1, 2, 3) 
t: List[Int] = List(-1, -2, -3) 

scala> val pairs = l zip t 
pairs: List[(Int, Int)] = List((1,-1), (2,-2), (3,-3)) 

И вот еще одна возможность, что вы могли бы просить

scala> val crossProduct = for (x <- l; y <- t) yield (x,y) 
crossProduct: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3)) 

Чем позже это просто синтаксический сахар для

scala> val crossProduct2 = l flatMap {x => t map {y => (x,y)}} 
crossProduct2: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3)) 

Третья возможность - вы хотите чередовать их

scala> val interleaved = for ((x,y) <- l zip t; r <- List(x,y)) yield r 
interleaved: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10) 

Это синтаксис для

scala> val interleaved2 = l zip t flatMap {case (x,y) => List(x,y)} 
interleaved2: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10) 
+0

Думаю, он просто хочет интерполировать списки. –

+0

Право, я хотел их чередовать, так что оба они дают тот же результат: [James] val interleaved = for ((x, y) <- l zip t; r <- List (x, y)) дают r [Даниэль] для (я <- от 0 до 10; г <- Список (л (я), т (я))) выход т Я думаю, Джеймс более элегантной и он также выводит список , Большое спасибо ребятам. –

0

Видимо, нет. Я получаю ошибку компиляции, когда я пытаюсь.

Похоже, для .. yield - это выражение. У вас не может быть двух уроков, так как это не является частью выражения.

Если вы хотите получить несколько значений, почему бы не привести их в качестве кортежа или списка?

Например:

for(t <- List(1,2,3); l <- List(-1,-2,-3)) 
    yield (t, l) 
0

Может выход не лучший способ пойти? Возможно, здесь может быть использовано простое добавление массива.

+0

Не существует семантической разницы между использованием урожая и использованием списка. Практическая разница связана с использованием памяти, где урожайность более эффективна для больших наборов. – Christopher

5

Нет, вы не можете использовать множественные предложения, но есть обходные пути. Например:

for (i <- 0 to 10; 
    r <- List(l(i), t(i))) 
yield r 

Вы можете гнездо для-постижений, конечно, но это приведет к списку списков элементов, которые я не верю, что вы хотите.

+1

Предупреждение, это решение - O (n^2) –

+0

Для списков l & t, что было, я уступлю его примеру. Если t & l были массивами или функциями, это не так, верно? –

+0

Правильно, для массивов индексированный доступ равен O (1), поэтому решение будет O (n). –

1

Здесь типа агностика решения для неизвестного, различного числа элементов в неизвестном количестве списков:

def xproduct (xx: List [List[_]]) : List [List[_]] = 
    xx match { 
    case aa :: bb :: Nil => 
     aa.map (a => bb.map (b => List (a, b))).flatten  
    case aa :: bb :: cc => 
     xproduct (bb :: cc).map (li => aa.map (a => a :: li)).flatten 
    case _ => xx 
} 

Для 2 Lists это перегружена. Вы могли бы назвать это

xproduct (List (l, t)) 
2

Урожайность может быть вложенной, что приведет к ...

for (i <- 0 to 3) yield { 
    for (j <- 0 to 2) yield (i,j) 
} 

в Вектор Вектор:

scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[(Int, Int)]] 
= Vector(Vector((0,0), (0,1), (0,2)), Vector((1,0), (1,1), (1,2)), Vector((2,0), (2,1), (2,2)), Vector((3,0), (3,1), (3,2))) 

for (i <- 0 to 3; 
    j <- 0 to 2) yield (i,j) 

Сглаженный решение семантически отличается.