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?

4
  • 3
    have you tried somthing? please have a look here: minimal reproducible example Commented Nov 24, 2016 at 8:43
  • nina will make your array to rocket but first you have to show her what you have tried . Commented Nov 24, 2016 at 8:45
  • If you are going to try yourself this will help you : stackoverflow.com/questions/35574784/… Commented Nov 24, 2016 at 8:47
  • Store it in object with Act1, Act2... as keys and then you can just use query's extend to merge it. Check here: jsfiddle.net/3epzp1s2 Commented Nov 24, 2016 at 8:48

4 Answers 4

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; }

Sign up to request clarification or add additional context in comments.

Comments

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);

Comments

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);

Comments

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"}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.