2016-10-31 3 views
1

Нужна помощь с Scala flatten.Scala flatten list of String и List [String]

У меня есть список String и List[String].

Пример: List("I", "can't", List("do", "this"))

Ожидая результат: List("I", "can't", "do", "this")

Я сделал много экспериментов, и самое компактное решение:

val flattenList = list.flatten { 
    case list: List[Any] => list 
    case x => List(x) 
} 

Но, кажется, очень сложно и трудно понять, , Любые предложения для более наивного кода?

Спасибо.

+0

http://stackoverflow.com/questions/1737452/how-to-flatten-a-list-of-different-types-in-scala – dkolmakov

+0

Вы попробовали 'list.flatten'. Если да, почему это не сработало для вас? – maasg

+0

@maasg: 'flatten' не будет работать, потому что список содержит разные типы данных, как String, так и List [String] – Shankar

ответ

1

Я не думаю, что вы можете избежать иметь дело с 2 случаями: один элемент против списка. Так или иначе вам нужно будет сказать вашей программе, что делать. Вот более общая реализация, которая имеет дело со списком любой глубины:

def flattenList(xs: List[Any]): List[Any] = 
    xs match { 
    case Nil => Nil 
    case (ys:List[_]) :: t => flattenList(ys) ::: flattenList(t) 
    case h :: t => h :: flattenList(t) 
    } 

Пример:

scala> flattenList(List("I", "can't", List("do", "this"))) 
res1: List[Any] = List(I, can't, do, this) 

scala> flattenList(List("I", "can't", List("do", List("this", "and", "this")))) 
res2: List[Any] = List(I, can't, do, this, and, this) 

Это не выглядит очень типобезопасен хотя. Попробуйте использовать дерево или что-то еще.

3

Что такое «сложное и трудное для понимания» - это ваши элементы микширования разного типа в том же списке. Это основная причина вашей проблемы. После того, как вы это сделаете, вам не нужно проверять список и проверять тип каждого элемента, чтобы исправить его, и ваше решение к нему так же хорошо, как и любое (конечно, лучше того, которое предлагается в другом ответ :)).

Я действительно переосмыслил бы путь кода, который приведет к тому, что в этом случае будет разнородный список, хотя, если бы я был вами. Это не очень хороший подход, потому что вы таким образом подорваете безопасность типа, и в итоге получаете List[AnyRef], который может содержать ... ну, что угодно.

+0

Да. Ты прав. Я новичок в scala, иногда функции языка приводят к плохим решениям только потому, что они работают :) Но в этом случае я должен начать рефакторинг. Спасибо. – antonkw

+0

Точно мои мысли. Я искушаюсь +1, но, строго говоря, это скорее комментарий, чем ответ. – maasg

+0

@maasg это ответ, все в порядке. Вопрос состоял в том, был ли лучший способ сгладить, чем ОР. Ответ - нет". :) – Dima

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