son satırıSon durumu Scala for döngüsünde farklı şekilde ele almanın bir yolu var mı? Örneğin
println("}")
son satırıSon durumu Scala for döngüsünde farklı şekilde ele almanın bir yolu var mı? Örneğin
println("}")
eşleşen deseni kullanabilmesi
last
fonksiyon Lists
gelince, onlar için "etkili bir sabit zaman" alır, çünkü Vectors
için gayet iyi, ben, lineer zaman alır Anlamada println
'dan kaçınmanızı öneririz. Bazen bir koleksiyonun ortasında meydana gelen bir hatayı takip etmek için yararlı olabilir, ancak aksi halde yeniden düzenleme ve test etmenin zor olduğu kodlara yol açar.
Genel olarak, herhangi bir tür yan etkinin nerede meydana gelebileceğini kısıtlayabiliyorsanız, genellikle hayat daha kolay hale gelir. Bunu yerine:
for (line <- myData) {
println("}, {")
}
Sen yazabilirsiniz: Ben de çıktıda her satırın içeriğini istediğini burada bir tahmin alacağım
val lines = for (line <- myData) yield "}, {"
println(lines mkString "\n")
!
val lines = for (line <- myData) yield (line + "}, {")
println(lines mkString "\n")
sadece doğrudan mkString
kullanılırsa yine daha iyi olurdu rağmen - bu ne için olduğunu bu! Önce bir String
üreten konum nasıl
val lines = myData.mkString("{", "\n}, {", "}")
println(lines)
Not sonra tek işlemde yazdırmadan. Bu yaklaşım kolayca ayrı yöntemlere bölünebilir ve sınıfınızda toString
uygulamak veya oluşturulan String'i testlerde denetlemek için kullanılabilir.
Sen bir örnek olarak TraversableOnce
özelliğin addString fonksiyonunu alabilir yazdırmak için ben almak için bir yol
for (line <- myData) {
println("}, {")
}
var mı olduğunu varsayalım. Senin durumunda
def addString(b: StringBuilder, start: String, sep: String, end: String): StringBuilder = {
var first = true
b append start
for (x <- self) {
if (first) {
b append x
first = false
} else {
b append sep
b append x
}
}
b append end
b
}
, ayırıcı }, {
ve bitiş }
+1. Standart kütüphanede nasıl yapıldığını görmek güzel. –
sen yararlanmak için kodunuzu refactor Can yerleşik mkString
?
scala> List(1, 2, 3).mkString("{", "}, {", "}")
res1: String = {1}, {2}, {3}
yerleşik kullanmak için mkString fonksiyonu istemiyorsanız, sen yapabilirsiniz
for (line <- lines)
if (line == lines.last) println("last")
else println(line)
GÜNCELLEME gibi bir şey: Açıklamalarda belirtildiği didierd gibi, bu çözüm son değere çünkü yanlış Birkaç kez oluşabilir, onun answer onun daha iyi bir çözüm sağlar. Daha ileri gitmeden önce
@tailrec
def printLines[A](l: List[A]) {
l match {
case Nil =>
case x :: Nil => println("last")
case x :: xs => println(x); printLines(xs)
}
}
Yinelemeli çözüm gayet iyi. Son öğenin değerinin başka hiçbir yerde gerçekleşmediğini bilemezseniz == lines.last olanı yanlıştır. –
@didierd teşekkürler, onu özledim. Cevaptaki hatayı işaret ettim. – 4e6
'==' yerine 'eq' kullanarak denedim ve hala çalışmıyor - Dizeler bir önbellek tutmalı, ki bu biraz acıdır –
mkstring
kullanımı hakkında daha önce söylediklerinize tam olarak katılıyorum ve sonuncu yerine ilk yinelemeyi ayırt ediyorum. Son olarak, scala koleksiyonlarının birbirinden ayırt etmenizi ister misiniz? Tüm öğeleri döndüren son satır init
yöntemine sahiptir. Yani
for(x <- coll.init) workOnNonLast(x)
workOnLast(coll.last)
(ilk ama ilk ve ve hepsi baş ve kuyruk tersinin init
ve last
olmanın sıralama) yapabilirsiniz. Ancak, yapıya bağlı olarak, pahalı olabilirler. Vector
'da, hepsi hızlı. List
'da, baş ve kuyruk temelde ücretsiz iken, init
ve last
, listenin uzunluğunda doğrusaldır. toplama boş olabilir zaman headOption
ve lastOption
haklı mkString
işaret vardır
for (x <- coll.lastOption) workOnLast(x)
Diğer cevaplar ile workOnlast
yerine size yardımcı olabilir ve verilerin normal miktarı için ben de o kullanırsınız. Ancak, mkString
mkString
, StringBuilder
aracılığıyla bellekte son sonucu oluşturan (biriktiren) (biriktirir) oluşturur (0,). Bu, sahip olduğumuz veri miktarına bağlı olarak her zaman arzu edilmez.
Bu durumda, tek istediğimiz "yazdırmak" ise, önce büyük sonucu oluşturmaya gerek yoktur (ve belki bundan kaçınmak isteriz). Tüm elemanlar üzerinde dolaşır ve mantıksal bir değer ile, sırayla her eleman geçen operation
çağırır
def forEachIsLast[A](iterator: Iterator[A])(operation: (A, Boolean) => Unit): Unit = {
while(iterator.hasNext) {
val element = iterator.next()
val isLast = !iterator.hasNext // if there is no "next", this is the last one
operation(element, isLast)
}
}
:
bu yardımcı işlevinin uygulama göz önünde bulundurun. Öğe, geçen son isetrue
değeridir.
Senin durumunda
böyle kullanılabilir:
forEachIsLast(myData) { (line, isLast) =>
if(isLast)
println("}")
else
println("}, {")
}
Biz burada şu avantajları vardır:
Ya da, biraz daha zarif, belki: 'forEachIsLast' sadece 'val it = seq olabilir.toIterator it.foreach {operation (_, it.hasNext)} ' –
Çok teşekkürler @ TheArchetypalPaul! Önerinizi önerinize dayalı bir uygulama kullanmak için düzenledim. –
verileri okuyabilir sonuncusu değil. İlk iterasyonu tanımlamak önemsizdir. –
+1 scala kullanmak için –