4

I have the below sample array.(original array has more than 200 elements)

var array = [
  {
    "clientid": "ID000002",
    "accesstoken": "pllALEl3TlwLL9hHP938H",
    "groupname": "ABC",
    "ancestorid": "8982857550",
    "stroyid": [
      "IGN-EXM-001-PDF",
      "IGN-EXM-002-PDF"
    ]
  }, {
    "clientid": "ID000002",
    "accesstoken": "pllALEl3TlwpHOD4aTP38H",
    "groupname": "EFG",
    "ancestorid": "4705872914",
    "stroyid": [
      "APP-ENE-FIE-CON",
      "APP-ENE-ASS-INS",
      "APP-ENE-ASS-CAR",
      "APP-ENE-MAT-REA"
    ]
  }, {
    "clientid": "ID000002",
    "accesstoken": "pllALEl3TlwLL9hHP938H",
    "groupname": "ABC",
    "ancestorid": "8982857550",
    "stroyid": [
      "IGN-EXM-001-ZIP",
      "IGN-EXM-002-ZIP"
    ]
  }
]

Condition = if (client id && ancestor id are the same then merge the storyid) so the output should be like:

[{
  "clientid": "ID000002",
  "accesstoken": "pllALEl3TlwLL9hHP938H",
  "groupname": "ABC",
  "ancestorid": "8982857550",
  "stroyid": [
    "IGN-EXM-001-PDF",
    "IGN-EXM-002-PDF",
    "IGN-EXM-001-ZIP",
    "IGN-EXM-002-ZIP"

  ]
}, {
  "clientid": "ID000002",
  "accesstoken": "pllALEl3TlwpHOD4aTP38H",
  "groupname": "EFG",
  "ancestorid": "4705872914",
  "stroyid": [
    "APP-ENE-FIE-CON",
    "APP-ENE-ASS-INS",
    "APP-ENE-ASS-CAR",
    "APP-ENE-MAT-REA"
  ]
}]

Please help me with javascript code to achieve this.

nem035
  • 34,790
  • 6
  • 87
  • 99
James_RajKumar
  • 201
  • 3
  • 12

4 Answers4

3

With plain Javascript, you could use a hash table as closure for grouping with clientid and ancestorid.

stroyid gets filtered for unique values.

var array = [{ clientid: "ID000002", accesstoken: "pllALEl3TlwLL9hHP938H", groupname: "ABC", ancestorid: "8982857550", stroyid: ["IGN-EXM-001-PDF", "IGN-EXM-002-PDF", "dupe"] }, { clientid: "ID000002", accesstoken: "pllALEl3TlwpHOD4aTP38H", groupname: "EFG", ancestorid: "4705872914", stroyid: ["APP-ENE-FIE-CON", "APP-ENE-ASS-INS", "APP-ENE-ASS-CAR", "APP-ENE-MAT-REA"] }, { clientid: "ID000002", accesstoken: "pllALEl3TlwLL9hHP9n", groupname: "ABC", ancestorid: "8982857550", stroyid: ["IGN-EXM-001-ZIP", "IGN-EXM-002-ZIP", "dupe"] }],
    result = array.reduce(function (hash) {
        return function (r, a) {
            var key = [a.clientid, a.ancestorid].join('|');
            if (!hash[key]) {
                hash[key] = { clientid: a.clientid, accesstoken: a.accesstoken, groupname: a.groupname, ancestorid: a.ancestorid, stroyid: a.stroyid };
                return r.concat(hash[key]);
            }
            hash[key].stroyid = hash[key].stroyid.concat(a.stroyid).filter(function (temp) {
                return function (a) {
                    return !temp[a] && (temp[a] = true);
                };
            }(Object.create(null)));
            return r;
        };
    }(Object.create(null)), []);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You can use the below to merge storyId without duplicates and then replace it with the original storyId array:

if(array[0].clientid == array[1].clientid && array[0].ancestorid == array[1].ancestorid){
var c = array[0].stroyid.concat(array[1].stroyid.filter(function (item) {
    return array[0].stroyid.indexOf(item) < 0;
}));
}
Ahmad Sanie
  • 3,678
  • 2
  • 21
  • 56
  • Ahmad..can you pls provide the for loop also .. I am not able to get the desired output.. I have updated the array in my post.. – James_RajKumar Feb 08 '17 at 17:33
1

const myArray = [
  { clientid: 1, ancestorid: 1, stroyid: ['a', 'b', 'c'] },
  { clientid: 1, ancestorid: 1, stroyid: ['a', 'b', 'd', 'e'] },
];

const newArray = myArray.reduce((newArray, entry) => {
  // Find if there is a duplicate in the new array
  const duplicate = newArray.find(newEntry => (
    entry.clientid === newEntry.clientid && entry.ancestorid === newEntry.ancestorid
  ));

  // If there is a duplicate, merge their stroyids
  if (duplicate) {
    const cleanIDs = entry.stroyid.filter(id => !duplicate.stroyid.includes(id));
    duplicate.stroyid = duplicate.stroyid.concat(cleanIDs);
  }
  else newArray.push(entry); // Else, add the entire entry

  return newArray;
}, []);

console.log(newArray);
  • hey thanks.. I am working in node.js and I get this error => array.reduce((newArray, entry) => { ^ SyntaxError: Unexpected token > – James_RajKumar Feb 08 '17 at 17:35
  • @user3742114 should be fixed now, try running the code snippet –  Feb 08 '17 at 17:49
1

One way you can approach this is to iterate through your array and add results to a Map based on a unique combination for your merging condition. Something like concatenation of ids should work.

If the map already had an object at this condition as its key, we merge the current item with the value, otherwise, we add it.

One bottleneck for your code is that you also require deep merging of these objects which isn't supported natively in JavaScript and is out of the scope of this question. You can check out this SO thread.

Here's an example (I'm using the deepmerge library for the merging):

var array=[{clientid:"ID000002",accesstoken:"pllALEl3TlwLL9hHP938H",groupname:"ABC",ancestorid:"8982857550",stroyid:["IGN-EXM-001-PDF","IGN-EXM-002-PDF"]},{clientid:"ID000002",accesstoken:"pllALEl3TlwpHOD4aTP38H",groupname:"EFG",ancestorid:"4705872914",stroyid:["APP-ENE-FIE-CON","APP-ENE-ASS-INS","APP-ENE-ASS-CAR","APP-ENE-MAT-REA"]},{clientid:"ID000002",accesstoken:"pllALEl3TlwLL9hHP9n",groupname:"ABC",ancestorid:"8982857550",stroyid:["IGN-EXM-001-ZIP","IGN-EXM-002-ZIP"]}];
    
const map = new Map();
const mergeKey = ({ clientid, ancestorid }) => `${clientid}${ancestorid}`;

for (const item of array) {
  const key = mergeKey(item);
  if (map.has(key)) {
    map.set(key, deepmerge(map.get(key), item));
  } else {
    map.set(key, item);
  }
}

const merged = Array.from(map.values());
console.log(merged);
<script src="https://unpkg.com/deepmerge@1.3.2/index.js"></script>

ES5 version if needed:

var array=[{clientid:"ID000002",accesstoken:"pllALEl3TlwLL9hHP938H",groupname:"ABC",ancestorid:"8982857550",stroyid:["IGN-EXM-001-PDF","IGN-EXM-002-PDF"]},{clientid:"ID000002",accesstoken:"pllALEl3TlwpHOD4aTP38H",groupname:"EFG",ancestorid:"4705872914",stroyid:["APP-ENE-FIE-CON","APP-ENE-ASS-INS","APP-ENE-ASS-CAR","APP-ENE-MAT-REA"]},{clientid:"ID000002",accesstoken:"pllALEl3TlwLL9hHP9n",groupname:"ABC",ancestorid:"8982857550",stroyid:["IGN-EXM-001-ZIP","IGN-EXM-002-ZIP"]}];
    
var map = Object.create(null);
function mergeKey(item) {
  return item.clientid + item.ancestorid;
}

array.forEach(function(item) {
  var key = mergeKey(item);
  if (map[key]) {
    map[key] = deepmerge(map[key], item);
  } else {
    map[key] = item;
  }
});

var merged = Object.keys(map).map(function(key) {
  return map[key];
});
console.log(merged);
<script src="https://unpkg.com/deepmerge@1.3.2/index.js"></script>
Community
  • 1
  • 1
nem035
  • 34,790
  • 6
  • 87
  • 99
  • I am getting this error in node.js => const mergeKey = ({ clientid, ancestorid }) => `${clientid}${ancestorid}`; ^ SyntaxError: Unexpected token , – James_RajKumar Feb 08 '17 at 17:26
  • @user3742114 It's probably because your node version doesn't support [ES6 destructuring](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment). I added an ES5 version as well. – nem035 Feb 08 '17 at 17:32