Mam wiele iteratorów, które zwracają elementy w posortowany sposób zgodnie z pewnym kryterium sortowania. Teraz chciałbym scalić (multipleksować) iteratory w jeden, połączony iterator. Wiem, jak to zrobić w stylu Java, np. tree-map, ale zastanawiałem się, czy istnieje bardziej funkcjonalne podejście? Chcę zachować lenistwo iteratorów tak bardzo, jak to tylko możliwe.Scala - scalanie wielu iteratorów
Odpowiedz
Można po prostu zrobić:
val it = iter1 ++ iter2
Tworzy kolejną iterację i nie ocenia elementy, ale opakowuje dwóch istniejących iteratory. Jest w pełni leniwy, więc nie powinieneś używać iter1
lub iter2
, gdy to zrobisz.
W ogóle, jeśli masz więcej iteratory do scalania, można użyć składane:
val iterators: Seq[Iterator[T]] = ???
val it = iterators.foldLeft(Iterator[T]())(_ ++ _)
Jeśli masz jakieś zamawiasz na elementach, które chcesz, aby utrzymać w wynikowym iteracyjnej ale chcesz lazyness, możesz konwertować je na strumienie:
def merge[T: Ordering](iter1: Iterator[T], iter2: Iterator[T]): Iterator[T] = {
val s1 = iter1.toStream
val s2 = iter2.toStream
def mergeStreams(s1: Stream[T], s2: Stream[T]): Stream[T] = {
if (s1.isEmpty) s2
else if (s2.isEmpty) s1
else if (s1.head < s2.head) s1.head #:: mergeStreams(s1.tail, s2)
else s2.head #:: mergeStreams(s1, s2.tail)
}
mergeStreams(s1, s2).iterator
}
Niekoniecznie szybciej, ale powinieneś to udoskonalić.
Ewentualną alternatywą jest użycie buffered iterators, aby uzyskać ten sam efekt.
OK, w jaki sposób mogę się upewnić, że zachowana jest względna kolejność według tych samych kryteriów sortowania? Powiedzmy, że mam obiekt, który ma znacznik czasu w postaci 'DateTime'. Chciałbym, aby te dwa iteratory zostały połączone z datownikami, a nie jedno po drugim (w Javie użyłbym komparatora) – Bober02
Edytowałem odpowiedź. – axel22
Dzięki, ale z całą pewnością nie chcę używać strumieni podczas buforowania elementów. Poza tym, czy mogę podać Zamawianie na rzeczywistych elementach np. jak w Java Comparator, który można przekazać do kolekcji jako argument? – Bober02
można spróbować:
(iterA ++ iterB).toStream.sorted.toIterator
Na przykład:
val i1 = (1 to 100 by 3).toIterator val i2 = (2 to 100 by 3).toIterator val i3 = (3 to 100 by 3).toIterator val merged = (i1 ++ i2 ++ i3).toStream.sorted.toIterator merged.next // results in: 1 merged.next // results in: 2 merged.next // results in: 3
Ups, moje złe. Widzę, że nie chcesz używać strumieni. –
@ axel22 Jak wspomniano, można to zrobić z BufferedIterators. Oto jeden strumień wolne rozwiązanie:
def combine[T](rawIterators: List[Iterator[T]])(implicit cmp: Ordering[T]): Iterator[T] = {
new Iterator[T] {
private val iterators: List[BufferedIterator[T]] = rawIterators.map(_.buffered)
def hasNext: Boolean = iterators.exists(_.hasNext)
def next(): T = if (hasNext) {
iterators.filter(_.hasNext).map(x => (x.head, x)).minBy(_._1)(cmp)._2.next()
} else {
throw new UnsupportedOperationException("Cannot call next on an exhausted iterator!")
}
}
- 1. Scala dla pętli i iteratorów
- 2. dołącz do wielu iteratorów w java
- 3. Java: Scalanie wielu plików dziennika według daty
- 4. Scalanie wielu identycznych tematów Strefy Kafki
- 5. Scalanie wielu ramek danych z plików CSV
- 6. Scalanie wielu zestawów elementów w jednym zestawie
- 7. Scalanie wielu tablic z jednej tablicy
- 8. Scala import wielu pakietów
- 9. Mieszanie wielu cech w Scala
- 10. Sortowanie Iteratorów PHP
- 11. Selektywne wyłączanie sprawdzanych iteratorów
- 12. wielowątkowe użycie `iteratorów ConcurrentHashMap`
- 13. Klonowanie iteratorów w Javie
- 14. git - scalanie różnicę oddziałów
- 15. Scalanie wielu ramek danych na dwóch wspólnych kolumnach
- 16. Scalanie wielu plików dziennika według daty włącznie multilinie
- 17. Pandy: scalanie wielu ramek danych i nazw kolumn kontrolnych?
- 18. pandy: scalanie (join) dwie ramki danych na wielu kolumnach
- 19. Scalanie wielu plików application.properties zamiast zamiany w Spring Boot?
- 20. Scalanie wielu wartości kolumn w jednej kolumnie w pand Pythona
- 21. Scalanie i sortowanie wielu plików XML za pomocą XSL
- 22. Scalanie wielu plików zrzutów tabeli .sql w jeden plik
- 23. Scalanie wielu wierszy w jedną kolumnę bez duplikatów
- 24. Scalanie wielu plików zip w jeden plik zip w Pythonie
- 25. Scalanie wielu niepowiązanych ramek danych w jedną pandę danych-ramka
- 26. Scalanie wierszy mających te same wartości w wielu kolumnach
- 27. Git: Scalanie wielu zatwierdzeń z jednego oddziału w inny
- 28. Scalanie wielu RecyclerView.Adapter do użytku z pojedynczym RecyclerView (Android)
- 29. Dlaczego nie mogliśmy przenosić iteratorów?
- 30. leniwy rodzaj iteratorów w Scali?
możliwe duplikat [Jak połączyć 2 iteratory w Scala?] (Http://stackoverflow.com/questions/9047856/how-to-combine-2-iterators-in -scala) –