cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
cassio_milanelo
Frequent Visitor

Combine array of objects with common keys

Let's say I have two arrays of objects:

 

[
  {
    "key": "a",
    "value": [1,2,3]
  },
  {
    "key": "b",
    "value": [1,2,3]
  },
  {
    "key": "c",
    "value": [1,2,3]
  }
]

 

and

 

[
  {
    "key": "b",
    "value": [8,9]
  },
  {
    "key": "d",
    "value": [1,2,3]
  },
  {
    "key": "a",
    "value": [4,5]
  },
  {
    "key": "e",
    "value": [3,4,5]
  }
]

 

 

Is there any painless way to combine both arrays keeping all the keys and merging the values?

The result could be either

 

[
  {
    "key": "a",
    "value": [1,2,3,4,5]
  },
  {
    "key": "b",
    "value": [1,2,3,8,9]
  },
  {
    "key": "c",
    "value": [1,2,3]
  },
  {
    "key": "d",
    "value": [1,2,3]
  },
  {
    "key": "e",
    "value": [3,4,5]
  }
]

 

or

 

[
  {
    "a": [1,2,3,4,5]
  },
  {
    "b": [1,2,3,8,9]
  },
  {
    "c": [1,2,3]
  },
  {
    "d": [1,2,3]
  },
  {
    "e": [3,4,5]
  }
]

 

 

Thank you!

1 ACCEPTED SOLUTION

Accepted Solutions
Paulie78
Super User
Super User

Was an interesting question, this does what you want, copy and paste again:

{"id":"cec54acd-d2f5-4d1c-8b4a-b094-60172b38","brandColor":"#8C3900","connectionReferences":{},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"Combine_Arrays","operationDefinition":{"type":"Scope","actions":{"Array1":{"type":"Compose","inputs":[{"key":"a","value":[1,2,3]},{"key":"b","value":[1,2,3]},{"key":"c","value":[1,2,3]}],"runAfter":{}},"Array2":{"type":"Compose","inputs":[{"key":"a","value":[4,5]},{"key":"b","value":[8,9]},{"key":"d","value":[1,2,3]}],"runAfter":{"Array1":["Succeeded"]}},"keyValues":{"type":"Select","inputs":{"from":"@union(outputs('Array1'), outputs('Array2'))","select":"@item()['key']"},"runAfter":{"Array2":["Succeeded"]}},"Unique_Keys":{"type":"Compose","inputs":"@union(body('keyValues'),body('keyValues'))","runAfter":{"keyValues":["Succeeded"]}},"eachKey":{"type":"Foreach","foreach":"@outputs('Unique_Keys')","actions":{"filterArray2":{"type":"Query","inputs":{"from":"@outputs('Array2')","where":"@equals(item()['key'], outputs('CurrentKey'))"},"runAfter":{"array1Values":["Succeeded"]}},"CurrentKey":{"type":"Compose","inputs":"@item()","runAfter":{}},"filterArray1":{"type":"Query","inputs":{"from":"@outputs('Array1')","where":"@equals(item()['key'], outputs('CurrentKey'))"},"runAfter":{"CurrentKey":["Succeeded"]}},"Combined":{"type":"Compose","inputs":{"key":"@{outputs('CurrentKey')}","value":"@union\r\n(\r\nif(equals(outputs('array1Values'), null), outputs('EmptyArray'), outputs('array1Values')),\r\nif(equals(outputs('array2Values'), null), outputs('EmptyArray'), outputs('array2Values'))\r\n)"},"runAfter":{"array2Values":["Succeeded"]}},"array1Values":{"type":"Compose","inputs":"@first(body('filterArray1'))?['value']","runAfter":{"filterArray1":["Succeeded"]}},"array2Values":{"type":"Compose","inputs":"@first(body('filterArray2'))?['value']","runAfter":{"filterArray2":["Succeeded"]}}},"runAfter":{"EmptyArray":["Succeeded"]}},"EmptyArray":{"type":"Compose","inputs":[],"runAfter":{"Unique_Keys":["Succeeded"]}},"newArray":{"type":"Compose","inputs":"@outputs('Combined')","runAfter":{"eachKey":["Succeeded"]}}},"runAfter":{}}}

View solution in original post

9 REPLIES 9
Paulie78
Super User
Super User

Certainly is possible. I've produced the output in both ways you demonstrated above:

2021-04-17_20-43-48.png

If you would rather not recreate this, you can simply copy this code into a flow and it will create the demo for you:

{"id":"83f219a9-d493-42b7-85f4-a47c-3ef98454","brandColor":"#8C3900","connectionReferences":{},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"Combine_Arrays","operationDefinition":{"type":"Scope","actions":{"Array1":{"type":"Compose","inputs":[{"key":"a","value":[1,2,3]},{"key":"b","value":[1,2,3]},{"key":"c","value":[1,2,3]}],"runAfter":{}},"Array2":{"type":"Compose","inputs":[{"key":"a","value":[4,5]},{"key":"b","value":[8,9]},{"key":"d","value":[1,2,3]}],"runAfter":{"Array1":["Succeeded"]}},"Select":{"type":"Select","inputs":{"from":"@range(0,length(outputs('Array1')))","select":{"key":"@outputs('Array1')[item()]['key']","value":"@union(outputs('Array1')[item()]['value'], outputs('Array2')[item()]['value'])"}},"runAfter":{"Array2":["Succeeded"]}},"Select_2":{"type":"Select","inputs":{"from":"@range(0, length(outputs('Array1')))","select":{"@{outputs('Array1')[item()]['key']}":"@union(outputs('Array1')[item()]['value'], outputs('Array2')[item()]['value'])"}},"runAfter":{"Select":["Succeeded"]}}},"runAfter":{}}}

Copy the code above into your clipboard, and then add a new step in a flow, go to "My clipboard" and click on "Combine Arrays".

 

Let me know how you get on.

cassio_milanelo
Frequent Visitor

That's a very elegant/comprehensive/efficient solution, but it misses the extra key "d" and "e" present in the second array.

The two original arrays will contain "keys" that are both common and unique among them. The common ones must be merged, and the unique ones (from both) must be kept.

 

Also, the number of keys will not be the same nor in the same order, so I don't think using index will be possible in this case (I edited the original question to make it more clear).

In addition to my previous answer, I just would like to add that the inputs array could be in the format below, if it's any easier:

[
  {
    "a": [1,2,3]
  },
  {
    "b": [1,2,3]
  },
  {
    "c": [1,2,3]
  }
]
[
  {
    "b": [8,9]
  },
  {
    "d": [1,2,3]
  },
  {
    "a": [4,5]
  },
  {
    "e": [3,4,5]
  }
]
Paulie78
Super User
Super User

**bleep**, so it does. In that case, the answer to your question, is there is not a painless way, but there is a way, but involves an apply to each loop. Do you want me to put it together for you?

@Paulie78, I appreciate your help.

Let me play around and I'll let you know if I need your brain.

Paulie78
Super User
Super User

Was an interesting question, this does what you want, copy and paste again:

{"id":"cec54acd-d2f5-4d1c-8b4a-b094-60172b38","brandColor":"#8C3900","connectionReferences":{},"connectorDisplayName":"Control","icon":"data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZlcnNpb249IjEuMSIgdmlld0JveD0iMCAwIDMyIDMyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPg0KIDxwYXRoIGQ9Im0wIDBoMzJ2MzJoLTMyeiIgZmlsbD0iIzhDMzkwMCIvPg0KIDxwYXRoIGQ9Im04IDEwaDE2djEyaC0xNnptMTUgMTF2LTEwaC0xNHYxMHptLTItOHY2aC0xMHYtNnptLTEgNXYtNGgtOHY0eiIgZmlsbD0iI2ZmZiIvPg0KPC9zdmc+DQo=","isTrigger":false,"operationName":"Combine_Arrays","operationDefinition":{"type":"Scope","actions":{"Array1":{"type":"Compose","inputs":[{"key":"a","value":[1,2,3]},{"key":"b","value":[1,2,3]},{"key":"c","value":[1,2,3]}],"runAfter":{}},"Array2":{"type":"Compose","inputs":[{"key":"a","value":[4,5]},{"key":"b","value":[8,9]},{"key":"d","value":[1,2,3]}],"runAfter":{"Array1":["Succeeded"]}},"keyValues":{"type":"Select","inputs":{"from":"@union(outputs('Array1'), outputs('Array2'))","select":"@item()['key']"},"runAfter":{"Array2":["Succeeded"]}},"Unique_Keys":{"type":"Compose","inputs":"@union(body('keyValues'),body('keyValues'))","runAfter":{"keyValues":["Succeeded"]}},"eachKey":{"type":"Foreach","foreach":"@outputs('Unique_Keys')","actions":{"filterArray2":{"type":"Query","inputs":{"from":"@outputs('Array2')","where":"@equals(item()['key'], outputs('CurrentKey'))"},"runAfter":{"array1Values":["Succeeded"]}},"CurrentKey":{"type":"Compose","inputs":"@item()","runAfter":{}},"filterArray1":{"type":"Query","inputs":{"from":"@outputs('Array1')","where":"@equals(item()['key'], outputs('CurrentKey'))"},"runAfter":{"CurrentKey":["Succeeded"]}},"Combined":{"type":"Compose","inputs":{"key":"@{outputs('CurrentKey')}","value":"@union\r\n(\r\nif(equals(outputs('array1Values'), null), outputs('EmptyArray'), outputs('array1Values')),\r\nif(equals(outputs('array2Values'), null), outputs('EmptyArray'), outputs('array2Values'))\r\n)"},"runAfter":{"array2Values":["Succeeded"]}},"array1Values":{"type":"Compose","inputs":"@first(body('filterArray1'))?['value']","runAfter":{"filterArray1":["Succeeded"]}},"array2Values":{"type":"Compose","inputs":"@first(body('filterArray2'))?['value']","runAfter":{"filterArray2":["Succeeded"]}}},"runAfter":{"EmptyArray":["Succeeded"]}},"EmptyArray":{"type":"Compose","inputs":[],"runAfter":{"Unique_Keys":["Succeeded"]}},"newArray":{"type":"Compose","inputs":"@outputs('Combined')","runAfter":{"eachKey":["Succeeded"]}}},"runAfter":{}}}

View solution in original post

@Paulie78 you're sick! 😊

 

That worked like a charm.

Thank you so much! 

cassio_milanelo
Frequent Visitor

@Paulie78, your solution works perfectly, and in addition, it contains a new concept for me.

 

On the last step inside the eachKey loop, the step "Combined" creates the object with the key/values, and outside the loop (step newArray) contains all of them together afterwards. 

How come the "newArray" gathers all the data? Isn't the value of "Combined" overwritten on every loop?
In any coding language, I'd expect the "newArray" to contain only the result of the last interaction.

Could you please give me some background or source for this concept?

 

cassio_milanelo_0-1618857298833.png

 

Paulie78
Super User
Super User

The value of combined comes out as an array of values, which end up in newArray. Lots of of the actions in your apply to each loop will be doing the same.

Helpful resources

Announcements
UG GA Amplification 768x460.png

Launching new user group features

Learn how to create your own user groups today!

Community Connections 768x460.jpg

Community & How To Videos

Check out the new Power Platform Community Connections gallery!

M365 768x460.jpg

Microsoft 365 Collaboration Conference | December 7–9, 2021

Join us, in-person, December 7–9 in Las Vegas, for the largest gathering of the Microsoft community in the world.

Top Solution Authors
Users online (2,302)