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 III
Super User III

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 III
Super User III

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 III
Super User III

**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 III
Super User III

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 III
Super User III

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
Process Advisor

Introducing Process Advisor

Check out the new Process Advisor community forum board!

MPA User Group

Welcome to the User Group Public Preview

Check out new user group experience and if you are a leader please create your group

V3_PVA CAmpaign Carousel.png

Community Challenge - Giveaways!

Participate in the Power Virtual Agents Community Challenge

Carousel 2021 Release Wave 2 Plan 768x460.jpg

2021 Release Wave 2 Plan

Power Platform release plan for the 2021 release wave 2 describes all new features releasing from October 2021 through March 2022.

Top Kudoed Authors
Users online (3,707)