www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Comparison of multidimensional associative arrays

reply Alexander Zhirov <azhirov1991 gmail.com> writes:
Not an easy task for me, maybe you can advise your compact 
solution. There are two associative arrays of type 
`string[string][int]`. It is necessary to find the differences 
and return them when comparing:

```d
[
     6:["id":"6", "deleted":"f", "name":"6.2_test"],
     5:["id":"5", "deleted":"f", "name":"5.6_test"],
     4:["id":"4", "deleted":"f", "name":"6.2_hwlister"],
     3:["id":"3", "deleted":"f", "name":"5.6_hwlister"],
     2:["id":"2", "deleted":"f", "name":"6.2"],
     1:["id":"1", "deleted":"f", "name":"5.6"]
]

[
     4:["id":"4", "deleted":"f", "name":"6.2_hwlister"],
     3:["id":"3", "deleted":"f", "name":"5.6_hwlister"],
     2:["id":"2", "deleted":"f", "name":"6.2"],
     1:["id":"1", "deleted":"f", "name":"5.6"]
]
```
Feb 08 2023
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/8/23 09:55, Alexander Zhirov wrote:
 the differences
Is it considered a difference if a key exists but the value is different? Or is that an error case if you encounter that?
 return them when comparing:
The representation seems difficult as well. When given this:
      6:["id":"6", "deleted":"f", "name":"6.2_test"],
and that:
      6:["id":"6", "deleted":"f" ],
Should the difference be 6:["name":"6.2_test"] ? And how to represent "missing from inner AA"? Just because this sounds complicated, I hope the data structure can be designed differently to be more friendly to this operation. (?) Ali
Feb 08 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Wednesday, 8 February 2023 at 18:08:40 UTC, Ali Çehreli wrote:
 Just because this sounds complicated, I hope the data structure 
 can be designed differently to be more friendly to this 
 operation. (?)

 Ali
This is the result of an SQL query. Roughly speaking, I need to compare the result of queries from two different databases and find different ones. The tables are the same, the only difference is in the content.
Feb 08 2023
prev sibling parent reply Anonymouse <zorael gmail.com> writes:
On Wednesday, 8 February 2023 at 17:55:03 UTC, Alexander Zhirov 
wrote:
 Not an easy task for me, maybe you can advise your compact 
 solution. There are two associative arrays of type 
 `string[string][int]`. It is necessary to find the differences 
 and return them when comparing:
Can you explain how you determine how/if two entries are different?
Feb 08 2023
parent reply Alexander Zhirov <azhirov1991 gmail.com> writes:
On Wednesday, 8 February 2023 at 18:57:00 UTC, Anonymouse wrote:
 Can you explain how you determine how/if two entries are 
 different?
I apologize. I have not written, in fact, what I need to get. Array `A` ```d [ 4:["id":"4", "deleted":"f", "name":"6.2"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"t", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ] ``` Array `B` ```d [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ] ``` Diff: ```d [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"] ] ``` That is, the result is arrays of table B that are missing OR not equal to arrays in table A.
Feb 08 2023
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 2/8/23 11:04, Alexander Zhirov wrote:

 That is, the result is arrays of table B that are missing OR not equal
 to arrays in table A.
This should do it: alias MyType = string[string][int]; // 'a' is subtracted from 'b' MyType difference(MyType b, MyType a) { MyType result; foreach (kv; b.byKeyValue) { auto existing = kv.key in a; if (!existing || (*existing != kv.value)) { result[kv.key] = kv.value; } } return result; } void main() { auto a = [ 4:["id":"4", "deleted":"f", "name":"6.2"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"t", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto b = [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto expected = [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"] ]; auto diff = difference(b, a); import std.format; assert(diff == expected, format!"UNEXPECTED: %s"(diff)); } Ali
Feb 08 2023
parent Alexander Zhirov <azhirov1991 gmail.com> writes:
On Wednesday, 8 February 2023 at 19:32:22 UTC, Ali Çehreli wrote:
 This should do it:
 [...]
Yes, it works! I'll try it tomorrow on a large array of data. Thank you very much! This turns out to be a simple loop with a comparison of the existence of a key (whether it is included in an array or not) and a comparison of an existing array as a value with another array by this key. I wonder if can add this to lambda? In one line.
Feb 08 2023
prev sibling parent Anonymouse <zorael gmail.com> writes:
On Wednesday, 8 February 2023 at 19:04:15 UTC, Alexander Zhirov 
wrote:
 [...]
I would write a data structure and use struct members to reason about things, but that's probably just preference. ``` import std; struct DatabaseEntry { int id = -1; string deleted; string name; this(string[string] aa) { this.id = aa["id"].to!int; this.deleted = aa["deleted"]; this.name = aa["name"]; } auto opEquals(typeof(this) that) const { return (this.id == that.id) && (this.deleted == that.deleted) && (this.name == that.name); } } auto buildSortedEntryRange(string[string][int] aa) { return aa .byValue .map!(entry => DatabaseEntry(entry)) .array .sort!((a,b) => a.id < b.id); } void main() { auto arrayA = [ 4:["id":"4", "deleted":"f", "name":"6.2"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"t", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto arrayB = [ 6:["id":"6", "deleted":"f", "name":"6.2_test"], 5:["id":"5", "deleted":"f", "name":"5.6_test"], 4:["id":"4", "deleted":"f", "name":"6.2_hwlister"], 3:["id":"3", "deleted":"f", "name":"5.6_hwlister"], 2:["id":"2", "deleted":"f", "name":"6.2"], 1:["id":"1", "deleted":"f", "name":"5.6"] ]; auto entriesFromA = buildSortedEntryRange(arrayA); auto entriesFromB = buildSortedEntryRange(arrayB); auto range = zip(StoppingPolicy.longest, entriesFromA, entriesFromB); foreach (entryA, entryB; range) { if (entryA != entryB) { writeln(entryB); // ... } } } ``` Output is: ``` DatabaseEntry(2, "f", "6.2") DatabaseEntry(4, "f", "6.2_hwlister") DatabaseEntry(5, "f", "5.6_test") DatabaseEntry(6, "f", "6.2_test") ```
Feb 08 2023