Add array flattening support#1152
Add array flattening support#1152timkimadobe merged 7 commits intoadobe:feature/historical-consequencefrom
Conversation
| @@ -46,7 +46,7 @@ class Event_EventHistoryRequestTests: XCTestCase { | |||
| let request = event.toEventHistoryRequest() | |||
|
|
|||
| // 6 top-level keys + 5 flattened inner dictionary keys | |||
There was a problem hiding this comment.
nit: Do we want to update this comment?
There was a problem hiding this comment.
Yes, thanks for catching that! Updated
| "a.b": ["c": 1], | ||
| "a": ["b": 2] |
There was a problem hiding this comment.
nit: can we also add a case where we have ["a.b" : 1 , "a": ["b": 2]] and verify the final dictionary has only one key a.b whose value is 2
There was a problem hiding this comment.
I agree it would be nice to deterministically test the merge order, but my understanding is that the test case as is would implicitly rely on Swift's dictionary key ordering which is also not guaranteed, and I don't think should be relied on in a test case. Given that we also document that in the case of flattened dictionary key collision the final result is undefined I dont think we should have to test the undefined-ness portion as all we're really testing is Swift's underlying dictionary ordering implementation.
I did create a new test case to validate that the two given values result in the same flattened key though:
func testSameKeyPathFromDifferentShapes() {
let dottedKey: [String: Any] = ["a.b": 1]
let nestedKey: [String: Any] = ["a": ["b": 1]]
XCTAssertEqualDictionaries(dottedKey.flattening(), nestedKey.flattening())
}Please let me know what you think!
spoorthipujariadobe
left a comment
There was a problem hiding this comment.
Looks good! Just a few nits on extra tests
cdhoffmann
left a comment
There was a problem hiding this comment.
LGTM, excellent documentation. Agree with Spoorthi on the collision testing.
timkimadobe
left a comment
There was a problem hiding this comment.
Thanks for the review @spoorthipujariadobe and @cdhoffmann! Updated based on feedback
| @@ -46,7 +46,7 @@ class Event_EventHistoryRequestTests: XCTestCase { | |||
| let request = event.toEventHistoryRequest() | |||
|
|
|||
| // 6 top-level keys + 5 flattened inner dictionary keys | |||
There was a problem hiding this comment.
Yes, thanks for catching that! Updated
| "a.b": ["c": 1], | ||
| "a": ["b": 2] |
There was a problem hiding this comment.
I agree it would be nice to deterministically test the merge order, but my understanding is that the test case as is would implicitly rely on Swift's dictionary key ordering which is also not guaranteed, and I don't think should be relied on in a test case. Given that we also document that in the case of flattened dictionary key collision the final result is undefined I dont think we should have to test the undefined-ness portion as all we're really testing is Swift's underlying dictionary ordering implementation.
I did create a new test case to validate that the two given values result in the same flattened key though:
func testSameKeyPathFromDifferentShapes() {
let dottedKey: [String: Any] = ["a.b": 1]
let nestedKey: [String: Any] = ["a": ["b": 1]]
XCTAssertEqualDictionaries(dottedKey.flattening(), nestedKey.flattening())
}Please let me know what you think!
…arity with Android
| valueAsString = String(describing: (value as! Double)) | ||
| case is Bool: | ||
| valueAsString = String(describing: (value as! Bool)) | ||
| case is NSNull: |
There was a problem hiding this comment.
Added filtering out for NSNull values in the FNV1A32 hash generation, since my understanding is their inclusion was never intended?
There was a problem hiding this comment.
Hey Tim, need clarification here. What was the behavior before here? If the value was nil, what would the default case string look like?
There was a problem hiding this comment.
The behavior before was when you pass in a key value pair like:
["key": NSNull()]the value would hit the last case, the default:
default:
valueAsString = String(describing: value)
}turning NSNull into "<null>" instead of being filtered out, and the string for the hash would be:
"key:<null>"
There was a problem hiding this comment.
Ok gotcha. Yeah was curious about what String(describing:value) did with NSNull. Thanks for grabbing that. I'm ok with this change but just want to be sure @sbenedicadb has some input here since he wrote this i believe.
There was a problem hiding this comment.
Of course! And yes, I discussed with Steve and he said:
"i'm good with adding it on the principle of keeping it consistent with the android behavior."
30f835b
into
adobe:feature/historical-consequence
Description
This PR implements array flattening support, where array indexes are placed in the key path using dot notation. This array flattening is used whenever top level or nested array structures need to be flattened to a single-level dictionary of key value pairs. It would affect use cases like:
Given
{ "array": [1, 2], "nested": {"a": "b"}, "key": "value" }array"array": [1, 2]"array.0": 1"array.1": 2keys using dot notation
nested"nested.a": "b""nested.a": "b"key"key": "value""key": "value"It also implements:
~all_urlso that arrays remain unflattened and preserve the existing behavior.~all_urlhandling.Impact
Explanation taken from (thank you @spoorthipujariadobe!):
This change affects how event data map is flattened in:
matchercondition: Since key lookup in nested lists was never supported, this is a net new feature for this case and shouldn't create any backwards compatibility issues.~all_url: Unsure if customers use this in their Launch rules and what impact this change might have. Please share if this is a breaking change for this case.Related Issue
Motivation and Context
Explanation taken from (thank you @spoorthipujariadobe!):
With the existing logic, if a map contains a nested list, it is considered as unsupported for flattening and the resulting flattened map has the list added as an object, making it impossible to lookup for an element at a specific index in the list for rules matcher condition.
We need this ability to support content card disqualification when the card is dismissed. The rule condition in this case verifies that the dismiss event happened on the specific card we want to disqualify and writes a disqualify event to event history as a consequence. To verify this card association, we need to look up and match the activity id which is present inside the propositions array in the dismiss event data.
Disqualify rule example:
How Has This Been Tested?
Screenshots (if appropriate):
Types of changes
Checklist: