2012-10-08 16 views
10

Co to jest skuteczny sposób na iterację tylko nieparzystych członków kolekcji w Scali, na podstawie pozycji indeksu?Iteracja przez nieparzystych członków kolekcji w Scali

Biorąc pod uwagę tę listę:

val fruits: List[String] = List("apples", "oranges", "pears", "bananas") 

Chcę pominąć jabłka i gruszki, i przetwarzają pomarańczy i bananów. Dzięki!

Aktualizacja oparta na odpowiedziach udzielonych:

Wow, każdy z trzech najlepszych odpowiedzi ma zasługi. Pierwotnie miałem na myśli słowo "wydajne" z perspektywy składni kolekcji Scala, a ja po prostu szukałem zręcznego sposobu na utworzenie podlisty do kolejnej iteracji. @Senia robi dobrą robotę wprowadzając funkcję slide(), świetną do tego konkretnego przypadku użycia, ale lubię też bardziej uogólnione podejście @ Briana używając zipWithIndex().

Jednakże, gdy weźmie się pod uwagę rzeczywiste brzmienie pytania, które pierwotnie zadano, oraz wydajność obliczeniową odpowiedzi @ sourcedelica, myślę, że on bierze nagrodę za tę.

+0

Żadna z dotychczasowych odpowiedzi nie dotyczy członków nieparzystych. Zamiast tego tworzą listę nieparzystych członków (które mogą następnie zostać poddane iteracji, oczywiście). Musi istnieć prosty sposób bezpośredniego iterowania ich ove? –

Odpowiedz

5

Oto sposób, aby bezpośrednio iteracyjne nad nieparzystych:

val fruits: List[String] = List("apples", "oranges", "pears", "bananas") 
//> fruits : List[String] = List(apples, oranges, pears, bananas) 

val oddFruitsIterator = 
    Iterator.from(1, 2).takeWhile(_ < fruits.size).map(fruits(_)) 
//> oddFruits : Iterator[String] = non-empty iterator 

oddFruitsIterator.foreach(println)      
//> oranges 
//> bananas 

Jeśli jest to duży zbiór i/lub wykonujesz wiele iteracji, a następnie rozważ konwersję najpierw na IndexedSeq, więc fruits(_) to O (1). Na przykład:

val fruitsIs = fruits.toIndexedSeq 
val oddFruits = Iterator.from(1, 2).takeWhile(_ < fruitsIs.size).map(fruitsIs(_)) 

Należy zauważyć, że sam iterator jest oddzielony od kolekcji, którą iteruje. Oto kolejny przykład, który sprawia, że ​​bardziej oczywiste:

scala> val oddSeqIterator = 
    (seq: Seq[String]) => Iterator.from(1, 2).takeWhile(_ < seq.size).map(seq(_)) 
oddSeqIterator: Seq[String] => Iterator[String] = <function1> 

scala> val fruits: List[String] = List("apples", "oranges", "pears", "bananas") 
fruits: List[String] = List(apples, oranges, pears, bananas) 

scala> oddSeqIterator(fruits) 
res0: Iterator[String] = non-empty iterator 

scala> res0.foreach(println) 
oranges 
bananas 
15
scala> List("apples", "oranges", "pears", "bananas").drop(1).sliding(1, 2).flatten.toList 
res0: List[java.lang.String] = List(oranges, bananas) 
11
val fruits: List[String] = List("apples", "oranges", "pears", "bananas") 

fruits.zipWithIndex.filter(_._2 % 2 == 1).map(_._1) 

res0: List[String] = List(oranges, bananas) 

zipWithIndex par każdego elementu w liście z indeksem podając:

List[(String, Int)] = List((apples,0), (oranges,1), (pears,2), (bananas,3))

filtr nieparzyste elementy z filter(_._2 % 2 == 1) podając:

List[(String, Int)] = List((oranges,1), (bananas,3))

map listy [(String, Int)] to tylko listy [String] biorąc pierwszy element każdej krotki z .map(_._1) podaniem:

List[String] = List(oranges, bananas)

+14

Alternatywnie, za każdym razem, gdy masz 'filter', po którym następuje' map', możesz łączyć je używając 'collect', np.' Fruits.zipWithIndex.collect {case (item, idx) if idx% 2 == 1 => item} ' –

+0

bardzo miły post tego w czynie! Pakiet kolekcji Scala usprawiedliwia jego użycie w przetwarzaniu rozproszonym. –

1

chciałbym zaproponować inną metodę, za pomocą rekurencji, która wydaje się mieć za mało operacji, jak to możliwe, moim zdaniem, nawet jeśli jest mniej fantazyjny niż inne rozwiązania.

def iterateOdd(myList:List[String]):List[String] = myList match{ 
    case _::odd::tail => odd::iterateOdd(tail) 
    case _ => Nil 
} 

Lub jeśli po prostu chcesz przetwarzać nieparzyste członków

def iterateOdd(myList:List[String]):Unit = myList match{ 
    case _::odd::tail => println(odd); iterateOdd(tail) 
    case _ => 
} 
-1
  • mam inne podejście do rozwiązywania tego typu problemu.
  • Możemy skorzystać z listy.metoda zakresu (początek, koniec).

List.range (0,5) da List (0,1,2,3,4)

  • Możemy generować Lista indeksów i możemy je filtrować

    scala> val fruits: List [String] = Lista ("jabłka", "pomarańcze", "gruszki", "banany")

    scala> Lista.range (0, fruits.length) .filter (_% 2 ! = 0) .map (x => owoce (x))

    ponowna s0: Lista [String] = Lista (pomarańcze, banany)

+0

List.range (0,5) da listę (0,1,2,3,4) –

Powiązane problemy