admin管理员组

文章数量:1401499

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.

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.

Share Improve this question edited Jul 12, 2017 at 6:11 nem035 35.5k6 gold badges92 silver badges104 bronze badges asked Feb 8, 2017 at 16:54 James_RajKumarJames_RajKumar 2311 gold badge3 silver badges12 bronze badges 4
  • Your example merged two entries with different ids. – user5183133 Commented Feb 8, 2017 at 16:58
  • @user3742114 thanks – James_RajKumar Commented Feb 8, 2017 at 17:22
  • what should happen with different accesstoken in grouped result? – Nina Scholz Commented Feb 8, 2017 at 17:42
  • access token would be same if id&ancestor id match – James_RajKumar Commented Feb 9, 2017 at 7:27
Add a ment  | 

4 Answers 4

Reset to default 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; }

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

One way you can approach this is to iterate through your array and add results to a Map based on a unique bination 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./[email protected]/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./[email protected]/index.js"></script>

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

本文标签: javascriptHow to compare elements of an array and merge based on a conditionStack Overflow