-2

I am iterating trough objects which could have same key, for exapmle:

let data = {};
// object 1
metadata:{
  datefrom: '2001'
}
// objeft 2
metadata:{
  dateto: '2002'
}

So when iterating they have same variable name objDataEl .

I am trying to assign them to the data object, but the problem is that only the last one gets assigned.

I've tried doing this:

data = Object.assign(data, objDataEl);

and

// strDataKey is = 'metadata'
data[strDataKey] = objDataEl;

But in both cases it got overwritten and only the last value was inserted into object.

After itteration it should look like this:

data: {
  metadata: {
    datefrom: '2001',
    dateto: '2002'
  }
}

Data structure looks like this:

data = [ { "metadata" : { "datefrom" : 2001 } }, { "metadata" : { "dateto" : 2015 } } ];

How can this be accomplished ?

Giedrius
  • 603
  • 1
  • 6
  • 26
  • Please show us the data structure with the objects you are iterating over – Dexygen Dec 21 '17 at 12:52
  • Possible duplicate of [How can I merge properties of two JavaScript objects dynamically?](https://stackoverflow.com/questions/171251/how-can-i-merge-properties-of-two-javascript-objects-dynamically) – Martin Schneider Dec 21 '17 at 12:52
  • @GeorgeJempty metadata is the structure. – Giedrius Dec 21 '17 at 12:53
  • 2
    Yes, but data can't have multiple properties named metadata, so either data has to be an array instead of an object, or you have multiple data objects with a metadata property inside an array. So it does matter what structure the entire thing you want to loop over has. – Shilly Dec 21 '17 at 12:55
  • I understand that, but metadata should be only used as a key reference of where the proprerties should be inserted – Giedrius Dec 21 '17 at 12:56
  • Yes, we understand that, but we need to know the entire structure. Which of the following is correct? `var data = [ { "metadata" : { "datefrom" : 2001 } }, { "metadata" : { "dateto" : 2015 } } ];` or `var dataWrapper = [ { "data" : { "metadata" : { "datefrom" : 2001 } } }, { "data" : { "metadata" : { "dateto" : 2015 } } } ];` or even `var dataWrapper = { "data1" : { "metadata" : { "datefrom" : 2001 } }, "data2" : { "metadata" : { "datefrom" : 2001 } } };` Can you just show the loop you tried so we can see that structure? Since saying they're all called objDataEl doesn't help much. – Shilly Dec 21 '17 at 13:01
  • first one is correct :) updated the original post – Giedrius Dec 21 '17 at 13:03

1 Answers1

1

A simple array reduction will do the trick.

        var mergeProperty = function mergeProperty( propertyName ) {
            return function( aggregation, record ) {
                aggregation[ propertyName ] = Object.assign( aggregation[ propertyName ] || {}, record[ propertyName ] );
                return aggregation;
            };
        };
        var data = [
            { "metadata" : { "datefrom" : 2001 } },
            { "metadata" : { "dateto" : 2015 } }
        ];
        var result = data.reduce( mergeProperty( 'metadata' ), {} );
        // ES6
        const mergePropertyES6 = propertyName => ( aggregation, record ) => {
            aggregation[ propertyName ] = Object.assign( aggregation[ propertyName ] || {}, record[ propertyName ] );
            return aggregation;
        };
        const dataES6 =  [
            { "metadata" : { "datefrom" : 2001 } },
            { "metadata" : { "dateto" : 2015 } }
        ];
        const resultES6 = dataES6.reduce( mergePropertyES6( 'metadata' ), {} );
        console.log( result );
        console.log( resultES6 );   
Shilly
  • 8,511
  • 1
  • 18
  • 24