2015-05-22 24 views
5

Scala posiada standardowy sposób podziału ciąg w StringOps.splitciąg podzielonego przez char

to zachowanie nieco zaskoczył mnie jednak.

Aby wykazać, korzystając z funkcji szybkiego ogólnospożywczy

def sp(str: String) = str.split('.').toList 

następujące wyrażenia wszyscy oceniają true

(sp("") == List("")) //expected 
(sp(".") == List()) //I would have expected List("", "") 
(sp("a.b") == List("a", "b")) //expected 
(sp(".b") == List("", "b")) //expected 
(sp("a.") == List("a")) //I would have expected List("a", "") 
(sp("..") == List()) // I would have expected List("", "", "") 
(sp(".a.") == List("", "a")) // I would have expected List("", "a", "") 

więc oczekiwać, że rozłam wróci tablicę (liczba a, wystąpień separator) + 1 elementy, ale tak nie jest.

Jest prawie powyżej, ale usuwa wszystkie ciągi kończące puste, ale to nie jest prawdą w przypadku dzielenia pustego łańcucha.

Nie udało mi się zidentyfikować wzoru tutaj. Jakie zasady stosuje StringOps.split?

Jeśli chodzi o punkty bonusowe, czy istnieje dobry sposób (bez zbytniego kopiowania/dodawania ciągów znaków), aby uzyskać oczekiwany podział?

Odpowiedz

3

Dla ciekawskich można znaleźć kod tutaj. https://github.com/scala/scala/blob/v2.12.0-M1/src/library/scala/collection/immutable/StringLike.scala

Zobacz funkcję podziału ze znakiem jako argumentem (wiersz 206).

Wydaje mi się, że ogólny wzorzec, jaki się tu dzieje, polega na tym, że wszystkie końcowe puste wyniki są ignorowane.

Z wyjątkiem pierwszego, dla którego "jeśli nie znaleziono znaku separatora, to po prostu wysłano cały ciąg" logika zostaje zastosowana.

Próbuję dowiedzieć się, czy jest wokół nich jakaś dokumentacja projektowa.

Ponadto, jeśli zamiast separatora użyjesz łańcucha zamiast znaku char, powrócisz do podziału regex w języku Java. Jak wspomniano w @LRLucena, jeśli podasz parametr limitu o wartości większej niż rozmiar, otrzymasz końcowe wyniki końcowe. zobacz http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#split(java.lang.String,%20int)

+0

Dziękuję, właśnie wysłałem prośbę o wyciągnięcie dokumentacji. – Martijn

2

Możesz użyć split z wyrażeniem regularnym. Nie jestem pewien, ale myślę, że drugi parametr jest największy rozmiar wynikowej tablicy.

def sp(str: String) = str.split("\\.", str.length+1).toList 
0

wydaje się być spójny z tymi trzema zasadami:

1) Trailing pustych podciągi są odrzucane.

2) Pusty podciąg jest uważany za końcowy, zanim zostanie uznany za wiodący, jeśli dotyczy.

3) Pierwszy przypadek bez separatorów jest wyjątkiem.

+0

wartości null? Mam nadzieję, że nie. – Martijn

+0

Wybacz moją rozlaną nomenklaturę. Powiedziałbym, że rozmawiałem ogólnie, ale potem znowu bym się wtrącił. Strumienie o długości zero. –

Powiązane problemy