Câu trả lời:
Tôi tin rằng bạn đang tìm kiếm zipWithIndex?
scala> val ls = List("Mary", "had", "a", "little", "lamb")
scala> ls.zipWithIndex.foreach{ case (e, i) => println(i+" "+e) }
0 Mary
1 had
2 a
3 little
4 lamb
Từ: http://www.artima.com/forums/flat.jsp?forum=283&thread=243570
Bạn cũng có các biến thể như:
for((e,i) <- List("Mary", "had", "a", "little", "lamb").zipWithIndex) println(i+" "+e)
hoặc là:
List("Mary", "had", "a", "little", "lamb").zipWithIndex.foreach( (t) => println(t._2+" "+t._1) )
while
vòng lặp, có lẽ là một trong những lựa chọn nhanh nhất.
view
bạn sẽ có thể ngăn việc tạo và duyệt qua một Danh sách bổ sung.
Sử dụng . bản đồ trong. zipWithIndex
val myList = List("a", "b", "c")
myList.zipWithIndex.map { case (element, index) =>
println(element, index)
s"${element}(${index})"
}
Kết quả:
List("a(0)", "b(1)", "c(2)")
map
theo yêu cầu thay vì chỉ in bên trong a foreach
.
Các giải pháp được đề xuất gặp phải thực tế là chúng tạo ra các tập hợp trung gian hoặc giới thiệu các biến không hoàn toàn cần thiết. Cuối cùng, tất cả những gì bạn cần làm là theo dõi số bước của một lần lặp. Điều này có thể được thực hiện bằng cách sử dụng ghi nhớ. Mã kết quả có thể trông giống như
myIterable map (doIndexed(someFunction))
Các doIndexed
-Function kết thúc tốt đẹp các chức năng bên trong mà nhận được cả một chỉ số một các yếu tố của myIterable
. Điều này có thể quen thuộc với bạn từ JavaScript.
Đây là một cách để đạt được mục đích này. Hãy xem xét tiện ích sau:
object TraversableUtil {
class IndexMemoizingFunction[A, B](f: (Int, A) => B) extends Function1[A, B] {
private var index = 0
override def apply(a: A): B = {
val ret = f(index, a)
index += 1
ret
}
}
def doIndexed[A, B](f: (Int, A) => B): A => B = {
new IndexMemoizingFunction(f)
}
}
Đây đã là tất cả những gì bạn cần. Bạn có thể áp dụng điều này ví dụ như sau:
import TraversableUtil._
List('a','b','c').map(doIndexed((i, char) => char + i))
kết quả nào trong danh sách
List(97, 99, 101)
Bằng cách này, bạn có thể sử dụng các chức năng Traversable thông thường với chi phí đóng gói chức năng hiệu quả của bạn. Chi phí là việc tạo ra đối tượng ghi nhớ và bộ đếm trong đó. Nếu không, giải pháp này tốt (hoặc xấu) về bộ nhớ hoặc hiệu suất như sử dụng unindexed map
. Thưởng thức!
coll.view.zipWithIndex
thay vìcoll.zipWithIndex
Có CountedIterator
trong 2.7.x (mà bạn có thể lấy từ một trình lặp bình thường với .counted). Tôi tin rằng nó đã không được dùng nữa (hoặc chỉ đơn giản là bị loại bỏ) trong 2.8, nhưng nó đủ dễ dàng để cuộn của riêng bạn. Bạn cần có thể đặt tên cho trình lặp:
val ci = List("These","are","words").elements.counted
scala> ci map (i => i+"=#"+ci.count) toList
res0: List[java.lang.String] = List(These=#0,are=#1,words=#2)
Hoặc giả sử bộ sưu tập của bạn có thời gian truy cập không đổi, bạn có thể ánh xạ danh sách chỉ mục thay vì bộ sưu tập thực tế:
val ls = List("a","b","c")
0.until(ls.length).map( i => doStuffWithElem(i,ls(i)) )
ls.indices.map(i => doStuffWithElem(i, ls(i))
indices
được thực hiện như0 until length
đó là khá nhiều điều tương tự: P
List
thực sự là nghèo. Tuy nhiên, tôi đã đề cập rằng điều này phù hợp nếu bộ sưu tập của bạn có thời gian truy cập liên tục. Nên đã chọn Array
.
Sử dụng .map trong .zipWithIndex với cấu trúc dữ liệu Bản đồ
val sampleMap = Map("a" -> "hello", "b" -> "world", "c" -> "again")
val result = sampleMap.zipWithIndex.map { case ((key, value), index) =>
s"Key: $key - Value: $value with Index: $index"
}
Các kết quả
List(
Key: a - Value: hello with Index: 0,
Key: b - Value: world with Index: 1,
Key: c - Value: again with Index: 2
)
Có hai cách để làm điều này.
ZipWithIndex: Tạo bộ đếm tự động bắt đầu bằng 0.
// zipWithIndex with a map.
val days = List("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
days.zipWithIndex.map {
case (day, count) => println(s"$count is $day")
}
// Or use it simply with a for.
for ((day, count) <- days.zipWithIndex) {
println(s"$count is $day")
}
Đầu ra của cả hai mã sẽ là:
0 is Sun
1 is Mon
2 is Tue
3 is Wed
4 is Thu
5 is Fri
6 is Sat
Zip : Sử dụng phương pháp zip với Luồng để tạo bộ đếm. Điều này cung cấp cho bạn một cách để kiểm soát giá trị bắt đầu.
for ((day, count) <- days.zip(Stream from 1)) {
println(s"$count is $day")
}
Kết quả:
1 is Sun
2 is Mon
3 is Tue
4 is Wed
5 is Thu
6 is Fri
7 is Sat
zipWithIndex
phương thức để lấy chỉ mục bên trong vòng lặp / bản đồ / bất cứ thứ gì.