Removing NSNull from Key Path Results with Partial Matches

Given a data structure with mismatching objects:


1> import Foundation
2> let d: NSDictionary = ["test": [["name": "Dick", "age": 101], ["name": "Jane"]]]


valueForKeyPath:
will return the values for the total number of sub-objects:


3> d.valueForKeyPath("test.name") as! NSArray
$R2: NSArray = "2 values" {
  [0] = "Dick"
  [1] = "Jane"
}


Even when the leaf key doesn't exist in all cases:


4> d.valueForKeyPath("test.age") as! NSArray
$R3: NSArray = "2 values" {
  [0] = Int64(101)
  [1] = {
    NSObject = {
      isa = NSNull
    }
  }
}


Is there some way to only get the existing

age
s, without an instances of
NSNull
?


@distinctUnionOfArrays
and so on helps if there are multiple sub-objects without the leaf key, but you're still left with the one
NSNull
.


On a somewhat side note, if the leaf key is entirely unknown, then only

NSNull
s are returned:


5> d.valueForKeyPath("test.dog") as! NSArray
$R4: NSArray = "2 values" {
  [0] = {
    NSObject = {
      isa = NSNull
    }
  }
  [1] = {
    NSObject = {
      isa = NSNull
    }
  }
}


In contrast, if the root key is unknown,

nil
is returned:


6> d.valueForKeyPath("dog.name")
$R5: AnyObject? = nil


This logic strikes me as inconsistent, but perhaps I'm missing something?


(This is cross-posted from Stack Overflow.)

The first thing you tried is a (fairly) obscure feature of KVC, where objects in a collection can be examined to see whether they respond to given method. The second thing is a (fairly) clunky feature of KVC that tries to provide some pseudo-scripting for bindings.


If you're doing this in code, use the NSDictionary method 'keysOfEntriesPassingTest' or 'keysOfEntriesWithOptions:passingTest'.


Removing NSNull from Key Path Results with Partial Matches
 
 
Q