3

Suppose I have an array:

var intArray: [Int] = [1,2,3,4,5] {
    didSet{
        //print index of value that was modified
    }
}

if I do intArray[2] = 10, what can I write inside didSet in order to print the index of the modified value (2, in this case) ?

Daniel
  • 7,357
  • 7
  • 32
  • 84
  • 1
    This is not possible, with `didSet` you can only get newValue(array) and oldValue(array). – Nirav D Jan 04 '17 at 05:46
  • really? is there some workaround for that? – Daniel Jan 04 '17 at 05:47
  • 2
    There's no built-in Swift way to do this, although you can write a custom solution like this: http://stackoverflow.com/a/27675375/6658553 – nathangitter Jan 04 '17 at 05:50
  • @Daniel You can write a wrapper for `Array` that forwards on all method calls, but intercepts the index as desired – Alexander Jan 04 '17 at 05:51
  • 1
    @nathan answer satisfied me :) is not exactly what I needed but my program was similar and I could adapt my code easily – Daniel Jan 04 '17 at 05:59
  • If you're willing to give up type safety (not recommended), see http://stackoverflow.com/questions/302365/observing-an-nsmutablearray-for-insertion-removal – Cristik Jan 04 '17 at 07:27

1 Answers1

7

The zip() function could be useful for this:

class A
{
   var array = [1,2,3,4,5]
   {
     didSet 
     { 
        let changedIndexes = zip(array, oldValue).map{$0 != $1}.enumerated().filter{$1}.map{$0.0}
        print("Changed indexes: \(changedIndexes)")
     }
   }
}

let a = A()
a.array = [1,2,7,7,5]

//  prints:  Changed indexes: [2, 3]

It also works for single element changes but arrays are subject to multiple changes so its safer to get an array of changed indexes.

Alain T.
  • 40,517
  • 4
  • 31
  • 51
  • Interesting idea. Of course this will only work for in-place modifications and not so well for insertions and deletions, as every element after the insertion/deletion would be considered changed. – devios1 Apr 10 '17 at 15:41
  • 1
    Agreed, and it also will not signal deleted element indexes. It does work in the limited scope of the OP's stated requirement (which he may find is but one use case in the long run). – Alain T. Apr 10 '17 at 15:58