
- Post History
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
07-27-2018 04:49 AM - edited 11-10-2023 06:32 AM
NOTE: MY POSTINGS REFLECT MY OWN VIEWS AND DO NOT NECESSARILY REPRESENT THE VIEWS OF MY EMPLOYER, ACCENTURE.
DIFFICULTY LEVEL: INTERMEDIATE
Assumes having taken the class SSNF and has good intermediate level of knowledge and/or familiarity with Scripting in ServiceNow.
You might be familiar with with the baseline ServiceNow Script Include utility library JSUtil which contains a really useful method named unique. This method is used to de-duplicate an array. Well, here is a great method for doing the same thing on an object array.
1. Copy and paste the following script into Scripts - Background (read the comments to understand what is happing in the code):
Script:
var location = 'S-B: UniqueObjectList Test';
var myObjectList = [];
try {
// Build a list of objects with one duplicate
var myObject = {};
myObject.name = 'George Jetson';
myObject.title = 'Building Architect';
myObject.location = 'Dallas';
// the key, is um, the key to the whole de-dup thing. It is the field used
// to uniquely identify a particular record for de-duplication purposes
myObject.key = (myObject.name + '|' + myObject.title + '|' + myObject.location).toLowerCase() + '';
myObjectList.push(myObject);
myObject = {};
myObject.name = 'George Jetson'; // <-- the duplicate record
myObject.title = 'Building Architect';
myObject.location = 'Dallas';
myObject.key = (myObject.name + '|' + myObject.title + '|' + myObject.location).toLowerCase() + '';
myObjectList.push(myObject);
myObject = {};
myObject.name = 'Wilma Flintstone';
myObject.title = 'Boss';
myObject.location = 'Ft. Worth';
myObject.key = (myObject.name + '|' + myObject.title + '|' + myObject.location).toLowerCase() + '';
myObjectList.push(myObject);
// print off the number of objects before the de-duplication
gs.info('---> [{1}} myObjectList.length: {0}', [myObjectList.length, location]);
myObjectList = uniqueObjectList(myObjectList);
// print off the count of objects after the de-duplication
gs.info('---> [{1}} myObjectList.length: {0}', [myObjectList.length, location]);
// print off the keys of all the remaining objects.
var message = 'List: \n';
for (var i=0; i < myObjectList.length; i++) {
var item = myObjectList[i];
message += item.key + '\n';
}
gs.info('---> [{0}] {1}', [location, message]);
}
catch(err) {
gs.error('---> [{1}} ERROR: {0}', [err, location]);
}
// note that this uses the JavaScript function splice to delete a member of an array
// loop through the list and compare it against itself. The key is used here for the
// match.
function uniqueObjectList(objectArray) {
for( var i = 0; i < objectArray.length; i++){
for( var j = i + 1; j < objectArray.length; j++){
if( objectArray[j].key == objectArray[i].key ) {
objectArray.splice(j, 1); // delete the duplicate
--j; // reduce the array length by one
}
}
}
return objectArray;
}
2. Click on the Run script button. Your results will look like this.
*** Script: ---> [S-B: UniqueObjectList Test} myObjectList.length: 3.0
*** Script: ---> [S-B: UniqueObjectList Test} myObjectList.length: 2.0
*** Script: ---> [S-B: UniqueObjectList Test] List:
george jetson|building architect|dallas
wilma flintstone|boss|ft. worth
Additional Notes:
- The key field is what will be used to de-duplicate the list.
- The key field MUST be unique or this method will not work.
Really any field can be used, but it would have to be unique, and you would have to adapt the function to accept the field.
Add it to your favorite Script Include utility library. I use this all the function quite a bit.
Enjoy!
Steven Bell.
If you find this article helps you, don't forget to log in and mark it as "Helpful"!
Originally published on: 7-27-2018 06:49 AM
I updated the code and brought the article into alignment with my new formatting standard.
- 894 Views
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Ha! I am a big advocate of using built-in objects and methods. I think sooner or later most of us find a need to implement this solution.
This was my take on it, hope it helps:
function uniqueObjectList(objArray, prop) {
return objArray.filter(function(filterObj, pos, thisArray){
return thisArray.map(function(mapObj){
return mapObj[prop];
})
.indexOf(filterObj[prop]) === pos;
});
}
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Considering performance (speed) Map approach by tnargav wouldn't be optimal to use in performance oriented environments.
While the for loops from the original version aren't optimized, they should out perform a map time and again regardless of size.
I presume that some variation of while instead of for would yield even faster results.
Rewriting the original array to be an Object would avoid de-dups from the start (still useful approach).
A small test yields:
- Mark as Read
- Mark as New
- Bookmark
- Permalink
- Report Inappropriate Content
Correct, objects are always the place to go when possible.
I have tested it using objects to see what the difference is and here are the results:
Regards
Greg