Разверните набор [набор [строка]] в декартово произведение в Scala

У меня есть следующий набор наборов. Я не знаю заранее, какой длины это будет.

val sets = Set(Set("a","b","c"), Set("1","2"), Set("S","T"))

Я хотел бы развернуть его в декартово произведение:

Set("a&1&S", "a&1&T", "a&2&S", ..., "c&2&T")

Как Вы сделали бы это?

10
задан Ken Bloom 23 May 2010 в 15:56
поделиться

3 ответа

Думаю, я понял, как это сделать.

def combine(acc:Set[String], set:Set[String]) = for (a <- acc; s <- set) yield {
  a + "&" + s 
}

val expanded = sets.reduceLeft(combine)

expanded: scala.collection.immutable.Set[java.lang.String] = Set(b&2&T, a&1&S, 
  a&1&T, b&1&S, b&1&T, c&1&T, a&2&T, c&1&S, c&2&T, a&2&S, c&2&S, b&2&S)
17
ответ дан 3 December 2019 в 13:47
поделиться

Хороший вопрос. Вот один из способов:

scala> val seqs = Seq(Seq("a","b","c"), Seq("1","2"), Seq("S","T"))                  
seqs: Seq[Seq[java.lang.String]] = List(List(a, b, c), List(1, 2), List(S, T))

scala> val seqs2 = seqs.map(_.map(Seq(_)))
seqs2: Seq[Seq[Seq[java.lang.String]]] = List(List(List(a), List(b), List(c)), List(List(1), List(2)), List(List(S), List(T)))

scala> val combined = seqs2.reduceLeft((xs, ys) => for {x <- xs; y <- ys} yield x ++ y)
combined: Seq[Seq[java.lang.String]] = List(List(a, 1, S), List(a, 1, T), List(a, 2, S), List(a, 2, T), List(b, 1, S), List(b, 1, T), List(b, 2, S), List(b, 2, T), List(c, 1, S), List(c, 1, T), List(c, 2, S), List(c, 2, T))

scala> combined.map(_.mkString("&"))             
res11: Seq[String] = List(a&1&S, a&1&T, a&2&S, a&2&T, b&1&S, b&1&T, b&2&S, b&2&T, c&1&S, c&1&T, c&2&S, c&2&T)
12
ответ дан 3 December 2019 в 13:47
поделиться

Пришел после батла ;) но еще один:

sets.reduceLeft((s0,s1)=>s0.flatMap(a=>s1.map(a+"&"+_)))
6
ответ дан 3 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

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