Closed ScrambledBrain closed 3 years ago
@ScrambledBrain,
Thanks fot the idea but I am afraid that it will add to much complexity to the design and usage. Taken to objects like:
$a = ConvertFrom-jSON '
{
"One": 1,
"Two": 2,
"Three": {
"One": 11,
"Two": 22,
"Three": 33
}
}'
$b = ConvertFrom-jSON '
{
"One": 1,
"Two": 22,
"Three": {
"One": 11,
"Two": 2,
"Three": 33
}
}'
What would be the results of:
$a |Join $b -On One
$a |Join $b -On Two
$a |Join $b -On Three
And for a full join? should a parent with a child match considered as a whole or each (recursive) child as a separate relation?
$a |FullJoin $b -On One
$a |FullJoin $b -On Two
$a |FullJoin $b -On Three
I think it is better to use a separate function as Flatten-Object
for this.
@iRon7,
I need the function to update my imported JSON file with settings I need. It has to update existing values, add new properties with its values and let other properties stay as before. But this has to work with child properties too, not only on 1st level, so, flattening is not an option.
Unfortunately, PowerShell seems not to have functionality included for handling this need for JSON files directly and also not for PSObjects directly.
I hoped, your Join-Object covers it, but did not, so I just dropped an info here.
The function(s) at link mentioned above fulfilled this for me and truely go through the whole PSObject recursively.
@ScrambledBrain,
I have given it some more thought but I think that what you're suggesting is not possible from a common design view.
The general idea behind the Join-Object
cmdlet is to join/merge tables where a table is a list of objects (or hash tables, e.g. when using -AsHashTable
) each property reprecents a column. The relation between the list of objects is controlled by the -On
parameter (and if omitted, based on the line index). How the properties are merged is defined by the -Properties
parameter.
The problem is that there generally exist two recursive structures: Arrays and dictionaries (or objects) meaning that from a recursive view you might have arrays in arrays
, dictionaries in arrays
, arrays in dictionaries
and dictionaries in dictionaries
. I suspect that you only covering dictionaries in dictionaries
in your prototype. Even with a suggested -Recurse
parameter that is mutual exclusive with on it would be to my opinion impossible to control the in-depth (array) values and objects with another recursive list.
Taken this Wikipedia example for 1.json
:
{
"firstName": "John",
"lastName": "Smith",
"isAlive": true,
"age": 27,
"address": {
"streetAddress": "21 2nd Street",
"city": "New York",
"state": "NY",
"postalCode": "10021-3100"
},
"phoneNumbers": [
{
"type": "home",
"number": "212 555-1234"
},
{
"type": "office",
"number": "646 555-4567"
}
],
"children": [],
"spouse": null
}
What will the 2.json
structure be to:
@iRon7
yes, if I would update that data with ...
{
"firstName": "John",
"lastName": "Smith",
"phoneNumbers": [
{
"type": "home",
"number": "212 555-9999"
},
{
"type": "mobile",
"number": "999 555-8888"
}
]
}
... the home phone number should be updated, the mobile phone number should be added and the office phone number should stay as it is.
if this:
{
"type": "home",
"number": "212 555-9999"
},
Replaces the
{
"type": "home",
"number": "212 555-1234"
},
Why wouldn't
{
"type": "mobile",
"number": "999 555-8888"
}
replace the whole entry:
{
"type": "office",
"number": "646 555-4567"
}
???
There is no difference between the two entries.
(because both Type
and number
are different?, if yes, what should the 2.Json
be if I do want to replace both?)
In other words, what defines what should be added and what defines what should be replaced?
(not even talking about: how should I remove an entry?)
If you suggesting that e.g. an -On type
parameter should take care of this, then how should the cmdlet differentiate between a possible parent type:[...
at a higher level or a different branch?
Ah yep, JSON wouldn't "know" that. It is a pair validation of "property" : "value".
But these pairs are separated in 2 blocks within phoneNumbers. Each block should be handled by its own... maybe sorted before. But yep, that would be not easy to find out, which phone block should match to another.
But that case was not my case, so I didn't think about that in depth.
I used the other PSScript linked above for a case like this:
original:
{
"p1": "v1",
"p2": "v2",
"propertygroup1": {
"p1": "v1",
"p2": "v2"
}
}
update:
{
"p1": "v1111",
"p3": "v3",
"propertygroup1":{
"p1": "v1111",
"p3": "v3"
},
"propertygroup2":{
"p1": "v1"
}
}
result:
{
"p1": "v1111",
"p2": "v2",
"p3": "v3",
"propertygroup1":{
"p1": "v1111",
"p2": "v2",
"p3": "v3"
},
"propertygroup2":{
"p1": "v1"
}
}
But that case was not my case, so I didn't think about that in depth.
Exactly, which just makes it too specific to embed in a common Join-Object
script.
Meaning, I can't just add a recursion feature that only works for 50% (dictionaries but not arrays).
Anyone who will use this purposed feature might bounce into this limitation and report a bug which I can't resolve.
Unless you have some better idea how to implement this as a whole, I will close this issue.
I have closed this purpose as I do not have clear design for a full implementation for both recursive dictionaries and recursive arrays.
Hi, your Join-Object actually joins values only at 1st level as wanted by parameters given.
If a property does not consist of a flat value (like string or int and so on) but consists of another PSCustomObject with multiple Properties and values, your script overwrites the whole PSCustomObject-value with the other PSCustomObject-value instead of comparing them, which sub-value needs an update or which sub-property needs to be added regarding to the parameters given.
Maybe have a look at https://gist.github.com/Badabum/a61e49019fb96bef4d5d9712e07b2af7 who includes the recursion.
Hopefully you can add recursion too =)
Cheers.