Em ter, 29 de dez de 2015 às 00:30, Dany St-Amant via swift-evolution < swift-evolution@swift.org> escreveu:
The original example contains a bug which is present on all looping
version/alternative due to the mutating nature of the array. Using the zip
implementation:
var array = [ "", "a", "b", "c", "", "d" ]
var secondHalf = array[array.count/2..<array.count]
for (index, element) in zip(secondHalf.indices, secondHalf) {
if element == "" {
secondHalf.removeAtIndex(index)
}
}
The variable index cycles through 3,4 and 5; but in order to be able to
remove the right element beyond the first removal, the variable index
should have cycled through 3, 4 and 4 (as some elements got shifted after
the first mutation). Mutating the array/list which one loops over is a
risky business and is a nice source of bugs (including infinite loop). If
this (Index, Element) is further investigated, it should consider that one
may also want to do a insert(:atIndex:), and may expect the (Index,
Element) to have proper Index but only for the original Element.
Dany St-Amant
Le 28 déc. 2015 à 01:06, Kevin Ballard via swift-evolution < > swift-evolution@swift.org> a écrit :
What you're asking for can already be done with `zip(col.indices, col)`.
And in my experience the need for this sort of thing is rare enough that
there's no need to have a dedicated property for it in the stdlib. The few
times that I've needed this sort of thing, I've always just said
for index in col.indices {
let elt = col[index]
// ...
}
and that's pretty simple. But if I ever did need to map it, I'd just use
the aforementioned zip() expression.
-Kevin Ballard
On Sun, Dec 27, 2015, at 12:08 AM, Patrick Pijnappel via swift-evolution > wrote:
-- Introduction
There should be a property on CollectionType that returns a sequence of
(Index, Element) tuples.
Currently enumerate() is often used instead, but it is not well suited to
the task and can lead to bugs.
-- Motivation
Using enumerate() instead of an (Index, Element) sequence has two main
problems.
Both arise because enumerate() returns a sequence of (n, Element) tuples,
where n is the element *number*, instead of a sequence of (Index, Element)
.
1) It doesn't work for collections not indexed by integers.
2) It doesn't do what you might expect in some cases, as indices do not
always start at 0.
For example ArraySlice's indices do not: array[2..<5] starts with index 2.
Consider the following code to take the 2nd half of the array and remove
all empty elements:
var array = [ "", "a", "b", "c", "", "d" ]
var secondHalf = array[array.count/2..<array.count]
for (index, element) in secondHalf.enumerate() {
if element == "" {
secondHalf.removeAtIndex(index)
}
}
This code will crash (ignoring for a moment this should probably be using
filter).
-- Alternatives
The same effect can already be achieved using the following:
for index in collection.indices {
let element = collection[index]
// ...
}
However having a dedicated (Index, Element) sequence has the following
advantages:
a) It can help prevent people from using enumerate() inappropriately.
b) It is very common use case that deserves shortening.
c) It can be chained (e.g. to map).
-- Proposed Solution
Add a property/method on CollectionType that returns a sequence of (Index,
Element) tuples.
For example, using a property named indexed:
for (index, element) in collection.indexed {
// ...
}
This should be the preferred idiom when you want both the index and the
element.
Note that enumerate() does still have valid roles to play:
- When you actually do want the element number, not the index.
- When you have a SequenceType, as it isn't indexed.
-- Implementation
The feature could be entirely implemented using existing constructs:
extension CollectionType {
var indexed: AnySequence<(Index, Generator.Element)> {
return AnySequence(indices.lazy.map { ($0, self[$0]) })
}
}
Alternatively, a dedicated SequenceType and/or GeneratorType could be
added.
*_______________________________________________*
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution