0

I am trying to merge two arrays into one. First one has default configuration and the second one has actual one. I found very similar problem here, but in my specific case it does not work.

Default configuration:

[
  { configurationOption: 'X provisioning', platform: 'X', value: true },
  { configurationOption: 'Y provisioning', platform: 'Y', value: true },
  { configurationOption: 'Z provisioning', platform: 'Z', value: true }
]

Actual configuration:

[
  { platform: 'X', value: false },
  { platform: 'Y', value: true }
]

Expected result:

[
  { configurationOption: 'X provisioning', platform: 'X', value: false },
  { configurationOption: 'Y provisioning', platform: 'Y', value: true },
  { configurationOption: 'Z provisioning', platform: 'Z', value: true }
]

So basically what it needs to do is update 'value' property of default configuration, based on actual one, tricky part is that some of configurationItem does not exist in actual configuration and actual configuration is missing 'configurationOption' property.

var config = _.unionBy(actual, defaultConf, 'platform');

This line is the closest one I could get, but is missing 'configurationOption' property.

Here is CodePen so you can play around with it: https://codepen.io/anon/pen/oBwLMb?editors=0012

Community
  • 1
  • 1
Konrad Klimczak
  • 1,474
  • 2
  • 22
  • 44
  • maybe try to give method intstead of 'platofrm' string as third argument? are you sure its not working? Seems to be working here -> http://codepen.io/kejt/pen/PWjGWa?editors=1111 – Kasia Jan 23 '17 at 17:10
  • 1
    Isn't `_.merge(defaultConf, actual)` producing the desired result? – Constantin Harabara Jan 23 '17 at 17:18
  • Is each element in the actuals array guaranteed to be in one-to-one correspondence by platform with the elements in the defaults array? In other words, will the actuals array always contain platform X and Y in that order? –  Jan 23 '17 at 18:01
  • No, order can change in actual configuration, only default configuration is constant. – Konrad Klimczak Jan 23 '17 at 18:07

2 Answers2

1

Create a new array of objects based on defaults, each element of which is the result of merging that default with the corresponding actual data found in actuals, based on matching platform.

const defaults = [
  {configurationOption: 'X provisioning', platform: 'X', value: true}, 
  {configurationOption: 'Y provisioning', platform: 'Y', value: true}, 
  {configurationOption: 'Z provisioning', platform: 'Z', value: true}];

const actuals = [
  {platform: 'X', value: false}, 
  {platform: 'Y', value: true}];

var result = defaults.map(deflt => Object.assign(
  {}, 
  deflt, 
  actuals.find(actual => actual.platform === deflt.platform)));

console.log(result);
      

This could be rewritten using lodash if you so prefer, using _.map, _.assign, and _.find.

1

You can use _.merge(). So your code can be written as:

var config = _.merge({}, defaultConf, actual);
console.log(config);  

http://jsbin.com/yuyegamaka/edit?js,console

Update: If you want array as result, then

var config = _.merge([], defaultConf, actual);
Kevin Le - Khnle
  • 10,579
  • 11
  • 54
  • 80