2012-05-12 1 views
0

Рассмотрим этот список, состоящий из объектов, которые являются экземплярами конкретных классов:Ищете лучшее решение

A, B, Opt(A),C, Opt(D), F, Opt(C), G, Opt(H) 

я тусклый, чтобы нормализовать этот список, чтобы получить этот результат:

A, B, C, Opt(D), F, G, Opt(H) 

Как вы видите, если есть элементы A и Opt(A) Я заменяю их только A или другим способом, я должен удалить элемент OPT(A).

Я хотел бы:

  • наиболее оптимальное решение в среднем производительность
  • кратчайшее решение
+0

Так равные элементы могут появляться только один раз? И список отсортирован по алфавиту? Почему вы не используете Set? –

+0

Не нужно сортировать список. Как я сказал: если найдены оба элемента Opt (A) и просто A, они заменяются просто A. Надеюсь, я был достаточно ясен. – PrimosK

+0

Что вы имеете в виду с 'Opt'? Вы имеете в виду вариант? – ziggystar

ответ

2

Это может быть немного более кратким, так как фильтрация, что вы хотите ;-):

scala> List(1,2,3,Some(4),5,Some(5)) 
res0: List[Any] = List(1, 2, 3, Some(4), 5, Some(5)) 

scala> res0.filter { 
    | case Some(x) => !res0.contains(x) 
    | case _ => true 
    | } 
res1: List[Any] = List(1, 2, 3, Some(4), 5) 

редактировать: Для больших коллекций было бы хорошо использовать toSet или непосредственно использовать Set ,

2

не самое эффективное решение, но, конечно, просто один.

scala> case class Opt[A](a: A) 
defined class Opt 

scala> val xs = List(1, 2, Opt(1), 3, Opt(4), 6, Opt(3), 7, Opt(8)) 
xs: List[Any] = List(1, 2, Opt(1), 3, Opt(4), 6, Opt(3), 7, Opt(8)) 

scala> xs flatMap { 
    | case o @ Opt(x) => if(xs contains x) None else Some(o) 
    | case x => Some(x) 
    | } 
res5: List[Any] = List(1, 2, 3, Opt(4), 6, 7, Opt(8)) 
1

Если вы не заботитесь о том, чтобы затем эффективность приводит вас использовать Set:

xs.foldLeft(Set.empty[Any])({ case (set, x) => x match { 
    case Some(y) => if (set contains y) set else set + x 
    case y => if (set contains Some(y)) set - Some(y) + y else set + y 
}}).toList 

В качестве альтернативы:

val (opts, ints) = xs.toSet.partition(_.isInstanceOf[Option[_]]) 
opts -- (ints map (Option(_))) ++ ints toList 
+0

Ваше решение не будет работать со списком типа List (Some (1), 1) '. – drexin

+0

@drexin Он производит 'List (1)', который, если я правильно прочитал вопрос, является правильным ответом ...? –

+0

О, вы правы, я использовал ': paste' в repl, который вернул присваивание' xs'. Но уверены ли вы, что создаете экземпляры 'Option' для каждого значения в списке, затем выполняете поиск и всегда создаете новые неизменяемые экземпляры' Set' более эффективны, чем 'filter' с поиском' 'List'? Я думаю, что 'filter' на' xs.toSet' будет лучше. – drexin

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

  • Нет связанных вопросов^_^