-
Notifications
You must be signed in to change notification settings - Fork 42
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Indices are (wrongly?) assumed to be integers and zero-based #37
Comments
Thanks for your comments, @ole. You make a very valid point and, as always, in a well-articulated way.
I have toyed with the idea of supporting a generic index type (the collection’s). This would make it easy to apply table/collection view data source changes spanning multiple sections, for example, using (Now, more than a year later, I still feel like a newbie when it comes to Swift and haven’t yet taken the time to fully understand the problem and possible solutions.) Your suggestion to use the term offset where applicable is just excellent. I will do that and clarify the issue in the README. Thanks. |
I think even if you wanted to use the collection's generic index type, it's not going to work. Take strings as an example — or Say we want to compute: Changeset.edits(from: "ABC".characters, to: "😜BD".characters) The result should clearly be:
(I'm using "offset" here for what the library currently calls "index".) If we wanted to refactor the library to use the collection's index type rather than integer offsets, we run into a problem. Here's the transformation matrix:
The number before each character indicates the character's string index value. Notice that the index value of Now see what happens if we apply the first substitution (replace the It's probably possible (if difficult) to apply the current algorithm to strings using the string index type because the algorithm goes through the collections from left to right (top to bottom) and never has to consider values to the right (bottom) of the current element, but the |
Closed by #39. |
I have a comment regarding terminology.
The indices the library computes for the
Edit
steps are currently always integers and always zero-based (i.e. the first index is0
). This works great for the intended main use case (table and collection view updates) because the index paths of a table or collection view are also zero-based and composed of integers.However, it doesn't reflect the reality of Swift's collection types. For example,
ArraySlice
uses integer indices, but they aren't zero-based. If you compute the changeset for twoArraySlice
instances, the result is arguably wrong or at least confusing:If you tried to apply this changeset literally to the source collection (i.e. delete the element at index
0
fromsource
), youʼd get a crash becausesource
doesnʼt have an "index"0
.In a way, a similar issue is when you compute changesets for strings (as most of the unit tests do) because string indices are not integers, so saying something like "insert "a" at index 5" doesn't strictly make sense in Swift.
I find this a little confusing and misleading.
Changeset
appears to be generic for any collection, and yet it doesn't follow Swift's conventions where the term "index" has a very specific meaning.When I first noticed this "problem" I wanted to suggest replacing the integer indices in
Edit
andEditOperation
with the collection's index type (i.e. something likeT.Index
). On second thought, this doesn't make sense because a changeset would have to compute "virtual" indices for a collection that doesn't really exist, and since collections are free to invalidate any existing index upon mutation, I don't think you could compute the indices in a generic way. Moreover, using real collection indices would make supporting table/collection view updates harder, not easier.After writing all this, I realize that the way this works is actually the best solution for the given problem. Having written this, I'm going to submit it too, even though I don't have a specific suggestion. Feel free to close this issue, and maybe it will help others understand this better when they find it in search.
My only suggestion would be to make it clear that
Changeset
andEdit
aren't concerned with indices, but with offsets. I think if thedebugDescription
read"delete x at offset 0"
etc. I would have been less confused. This is exemplified by the use ofenumerated()
to compute thecolumn
value inedits(from:to:)
, sinceenumerated()
computes offsets from 0 and not indices (see http://khanlou.com/2017/03/you-probably-don't-want-enumerated/ for more info onenumerated()
and how it's often misinterpreted).The text was updated successfully, but these errors were encountered: