Twoja generacja liczb losowych może dać duplikaty ... czy to w porządku? Oto w jaki sposób można łatwo wygenerować 10 niepowtarzalne numery 1-100 (generując rozmieszczane losowo kolejność 1-100 i zajmując pierwsze dziesięć):
val r = scala.util.Random.shuffle(1 to 100).toList.take(10)
teraz po prostu można podzielić zakres 1-100 do tych, którzy są zawarte w losowo generowanych listy i tych, którzy nie są:
val (listOfA, listOfB) = (1 to 100).partition(r.contains(_))
teraz robić, co chcesz z tych dwóch list, np:
println(listOfA.mkString(","))
println(listOfB.mkString(","))
oczywiście, zawsze można po prostu przejść przez jedna lista jednym:
(1 to 100).map {
case i if (r.contains(i)) => println("yes: " + i) // or whatever
case i => println("no: " + i)
}
Co uważasz za prosty dla pętli w rzeczywistości nie ma. To zrozumiałe i jest to cukier składniowy, który usuwa sugestie połączeń map, płaskich map i filtrów. Tak, można go używać w taki sam sposób, jak w klasycznej pętli for, ale dzieje się tak tylko dlatego, że List jest w rzeczywistości monadą. Bez wchodzenia w zbyt wiele szczegółów, jeśli chcesz robić rzeczy w idiomatyczny sposób Scala ("funkcjonalny" sposób), powinieneś unikać pisania klasycznych iteracji dla pętli i wolisz zdobywać kolekcję danych, a następnie mapować ich elementy, aby wykonaj to, czego potrzebujesz. Zwróć uwagę, że kolekcje mają za sobą naprawdę bogatą bibliotekę, która pozwala na wywoływanie fajnych metod, takich jak partition
.
EDIT (kompletność):
Ponadto, należy unikać skutków ubocznych, lub przynajmniej przesunąć je tak daleko w dół drogi, jak to możliwe. Mówię o drugim przykładzie z mojej odpowiedzi. Powiedzmy, że naprawdę musisz się zalogować rzeczy (używałbyś programu rejestrującego, ale println
jest wystarczająco dobry dla tego przykładu). Robienie tego w ten sposób jest złe. Należy pamiętać, że w takim przypadku można użyć foreach
zamiast map
, ponieważ nie zbiera się wyników, a jedynie wykonuje efekty uboczne.
Dobrym sposobem byłoby obliczenie potrzebnych rzeczy przez zmodyfikowanie każdego elementu w odpowiedni ciąg. Więc obliczyć potrzebne łańcuchy i gromadzić je w results
:
val results = (1 to 100).map {
case i if (r.contains(i)) => ("yes: " + i) // or whatever
case i => ("no: " + i)
}
// do whatever with results, e.g. print them
Teraz results
zawiera listę stu „tak X” i „Nie X” strun, ale nie robić brzydkie rzeczy i przeprowadzić rejestrację jako efekt uboczny w procesie mapowania.Zamiast tego zmapowałeś każdy element kolekcji na odpowiadający ciąg (zauważ, że oryginalna kolekcja pozostaje nienaruszona, więc jeśli (od 1 do 100) została zachowana pewna wartość, to wciąż tam jest, mapowanie tworzy nową kolekcję) i teraz możesz zrobić cokolwiek chcesz z nim, np przekazać go do rejestratora. Tak, w pewnym momencie musisz zrobić "brzydki efekt uboczny" i zalogować rzeczy, ale przynajmniej będziesz miał specjalną część kodu, aby to zrobić, a nie będziesz mieszał go w logikę mapowania, która sprawdza, czy numer jest zawarte w losowej kolejności.
Am I czegoś brakuje lub nie dla '(dyr <- r = scala.util.Random.shuffle (Lista. fill (10) (true) + List.fill (90) (false))) {if (cond) ... else // not cond ...} 'zrób to? –