1

Lets say I have two arrays details1 and details2. Below are contents of the array

var details1 =[];
details1[0] = {'ActivityName' : 'Act1',
              'Status' : 'Done'};
details1[1] = {'ActivityName' : 'Act2',
              'Status' : 'InProgress'};
details1[2] = {'ActivityName' : 'Act5',
              'Status' : 'Done'};

var details2 =[];
details2[0] = {'ActivityName' : 'Act2',
              'Status' : 'Done'};
details2[1] = {'ActivityName' : 'Act3',
              'Status' : 'Done'};

I need to compare both the arrays and add missing items and update the status based on name in array details1. My output should be

var details1 =[];
details1[0] = {'ActivityName' : 'Act1',
              'Status' : 'Done'};
details1[1] = {'ActivityName' : 'Act2',
              'Status' : 'Done'};
details1[2] = {'ActivityName' : 'Act3',
              'Status' : 'Done'};
details1[3] = {'ActivityName' : 'Act5',
              'Status' : 'Done'};

What is the best way to achieve this?

Nagendira
  • 69
  • 5
  • 3
    have you tried somthing? please have a look here: [mcve] – Nina Scholz Nov 24 '16 at 08:43
  • nina will make your array to rocket but first you have to show her what you have tried . – Mahi Nov 24 '16 at 08:45
  • If you are going to try yourself this will help you : http://stackoverflow.com/questions/35574784/how-to-check-if-values-in-one-javascript-object-are-present-in-another-one – Niklesh Raut Nov 24 '16 at 08:47
  • Store it in object with `Act1`, `Act2`... as keys and then you can just use query's extend to merge it. Check here: https://jsfiddle.net/3epzp1s2/ – Martin Gottweis Nov 24 '16 at 08:48

4 Answers4

2

You could use a hash table as reference to the items.

var details1 = [{ ActivityName: 'Act1', Status: 'Done' }, { ActivityName: 'Act2', Status: 'InProgress' }, { ActivityName: 'Act5', Status: 'Done' }],
    details2 = [{ ActivityName: 'Act2', Status: 'Done' }, { ActivityName: 'Act3', Status: 'Done' }],
    hash = Object.create(null);

details1.forEach(function (a) {
    hash[a.ActivityName] = a;
});

details2.forEach(function (a) {
    if (hash[a.ActivityName]) {
        hash[a.ActivityName].Status = a.Status;
        return;
    }
    details1.push(hash[a.ActivityName] = a);
});

details1.sort(function (a, b) { return a.ActivityName.localeCompare(b.ActivityName); });

console.log(details1);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Convert both arrays to objects, merge them, sort keys and extract values:

var details1 =[];
details1[0] = {'ActivityName' : 'Act1','Status' : 'Done1'};
details1[1] = {'ActivityName' : 'Act2','Status' : 'InProgress'};
details1[2] = {'ActivityName' : 'Act5','Status' : 'Done1'};

var details2 =[];
details2[0] = {'ActivityName' : 'Act2','Status' : 'Done2'};
details2[1] = {'ActivityName' : 'Act3','Status' : 'Done2'};


let toObject = (a, key) => a.reduce((o, x) =>
    Object.assign(o, {[x[key]]: x}),
    {}
);

let merge = Object.assign(
    toObject(details1, 'ActivityName'),
    toObject(details2, 'ActivityName')
);

let result = Object.keys(merge).sort().map(k => merge[k]);

console.log(result);
georg
  • 211,518
  • 52
  • 313
  • 390
1

ES6+ solution using a Map.

The gist is to go through the first array and add all items to a map with ActivityName as the key and the actual object as the value. Then iterate through the second array and either merge with a value at an existing ActivityName key or add a new value.

Lastly, sort the result.

Note: This solution doesn't alter the existing arrays

const details1 = [{
  'ActivityName': 'Act1',
  'Status': 'Done'
}, {
  'ActivityName': 'Act2',
  'Status': 'InProgress'
}, {
  'ActivityName': 'Act5',
  'Status': 'Done'
}];

const details2 = [{
  'ActivityName': 'Act2',
  'Status': 'Done'
}, {
  'ActivityName': 'Act3',
  'Status': 'Done'
}];

const { assign } = Object;
const map = new Map();

const addToMap = (detail) => {
  const { ActivityName: name } = detail;
  if (map.has(name)) {
    // if detail already exists,
    // create a new object by merging the current detail and the new detail 
    detail = assign({}, map.get(name), detail);
  }
  map.set(name, detail); 
};

// add first then second details to a map
details1.concat(details2).forEach(addToMap);

// sort the keys and map them to values
const result = [...map.keys()]
  .sort()
  .map(key => map.get(key));

// show the new result (NOTE: old arrays are unchanged)
console.log(result);
nem035
  • 34,790
  • 6
  • 87
  • 99
0
var details1 = [];
details1[0] = {'ActivityName': 'Act1',
    'Status': 'Done'};
details1[1] = {'ActivityName': 'Act2',
    'Status': 'InProgress'};
details1[2] = {'ActivityName': 'Act5',
    'Status': 'Done'};

var details2 = [];
details2[0] = {'ActivityName': 'Act2',
    'Status': 'Done'};
details2[1] = {'ActivityName': 'Act3',
    'Status': 'Done'};

//Merge function
var __merge = function (arr1, arr2) {
    return arr1.concat(arr2).reduce(function (prev, current, index) {

        if (!(current.ActivityName in prev.keys)) {
            prev.keys[current.ActivityName] = index;
            prev.result.push(current);
        } else {
            prev.result[prev.keys[current.ActivityName]] = current;
        }

        return prev;
    }, {result: [], keys: {}}).result;
}; 

details1 = (__merge(details1, details2));

And that's the result :

[{ ActivityName="Act1",  Status="Done"}, { ActivityName="Act2",  Status="Done"}, { ActivityName="Act5",  Status="Done"}, { ActivityName="Act3",  Status="Done"}]
beta-developper
  • 1,689
  • 1
  • 13
  • 24