
- Subscribe to RSS Feed
- Mark as New
- Mark as Read
- Bookmark
- Subscribe
- Printer Friendly Page
- Report Inappropriate Content
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.
Something, as a developer, that I run into quite a bit is the need to remove duplicates from an Object List by a key or a value such as a sys_id. In this article I will describe how to do this with ServiceNow Scripting and JavaScript.
This a very useful type of functionality when dealing with any size object array. In the following example I will build a list (array) of cmdb_ci objects, build a key for each object in the list, and then use a function to remove all of the duplicates. The key is simply an attempt to build a unique identifier. This identifier can be a sys_id, or some combination of values that will allow the code to identify a unique record.
var incidentRecords = new GlideRecord('incident');
incidentRecords.addNotNullQuery('cmdb_ci');
incidentRecords.addActiveQuery();
incidentRecords.query();
var cmdbList = [];
// The following looping code is a GlideRecord inside of a GlideRecord.
// This is normally a BAD way of doing this, but I want
// to make SURE I have duplicates in the Object List!
while (incidentRecords.next()) {
var ciRecords = new GlideRecord('cmdb_ci');
if (ciRecords.get('sys_id', incidentRecords.getValue('cmdb_ci'))) {
cmdb_ci = {};
cmdb_ci.serial_number = ciRecords.getValue('serial_number');
cmdb_ci.name = ciRecords.getValue('name');
cmdb_ci.className = ciRecords.getValue('sys_class_name');
cmdb_ci.install_status = ciRecords.getValue('install_status');
cmdb_ci.key = cmdb_ci.serial_number + ':' + cmdb_ci.name + ':' + cmdb_ci.className;
cmdbList.push(cmdb_ci);
}
}
gs.info('BEFORE: {0}\n{1}', [cmdbList.length, JSON.stringify(cmdbList)]);
cmdbList = uniqueObjectList(cmdbList);
gs.info('AFTER: {0}\n{1}', [cmdbList.length, JSON.stringify(cmdbList)]);
function uniqueObjectList(dedupList) {
for (var i = 0; i < dedupList.length; i++) {
for (var j = i + 1; j < dedupList.length; j++) {
if (dedupList[j].key == dedupList[i].key) {
dedupList.splice(j, 1);
--j;
}
}
}
return dedupList;
}
Results:
*** Script: BEFORE: 18.0
[
{"serial_number":null,"name":"Saints and Sinners Bingo","className":"cmdb_ci_spkg","install_status":"1","key":"null:Saints and Sinners Bingo:cmdb_ci_spkg"},
{"serial_number":"L3CD257","name":"IBM-T42-DLG","className":"cmdb_ci_computer","install_status":null,"key":"L3CD257:IBM-T42-DLG:cmdb_ci_computer"},
{"serial_number":null,"name":"Windows XP Hotfix (SP2) Q817606","className":"cmdb_ci_spkg","install_status":"1","key":"null:Windows XP Hotfix (SP2) Q817606:cmdb_ci_spkg"},
{"serial_number":null,"name":"WeatherBug","className":"cmdb_ci_spkg","install_status":"1","key":"null:WeatherBug:cmdb_ci_spkg"},
{"serial_number":null,"name":"EFOWEB","className":"cmdb_ci_computer","install_status":"1","key":"null:EFOWEB:cmdb_ci_computer"},
{"serial_number":null,"name":"MailServerUS","className":"cmdb_ci_server","install_status":"1","key":"null:MailServerUS:cmdb_ci_server"},
{"serial_number":null,"name":"WEBSERVER","className":"cmdb_ci_computer","install_status":"1","key":"null:WEBSERVER:cmdb_ci_computer"},
{"serial_number":null,"name":"FileServerFloor2","className":"cmdb_ci_server","install_status":"1","key":"null:FileServerFloor2:cmdb_ci_server"},
{"serial_number":"L3BB911","name":"*JEMPLOYEE-IBM","className":"cmdb_ci_computer","install_status":"1","key":"L3BB911:*JEMPLOYEE-IBM:cmdb_ci_computer"},
{"serial_number":null,"name":"Sales Force Automation","className":"cmdb_ci_service","install_status":"1","key":"null:Sales Force Automation:cmdb_ci_service"},
{"serial_number":null,"name":"Sales Force Automation","className":"cmdb_ci_service","install_status":"1","key":"null:Sales Force Automation:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Controlling","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Controlling:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Financial Accounting","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Financial Accounting:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Human Resources","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Human Resources:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Materials Management","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Materials Management:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Sales and Distribution","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Sales and Distribution:cmdb_ci_service"},
{"serial_number":"cx320-4001-21a","name":"nyc rac nas200","className":"cmdb_ci_msd","install_status":"1","key":"cx320-4001-21a:nyc rac nas200:cmdb_ci_msd"},
{"serial_number":null,"name":"EXCH-SD-05","className":"cmdb_ci_email_server","install_status":"1","key":"null:EXCH-SD-05:cmdb_ci_email_server"}
]
*** Script: AFTER: 17.0
[
{"serial_number":null,"name":"Saints and Sinners Bingo","className":"cmdb_ci_spkg","install_status":"1","key":"null:Saints and Sinners Bingo:cmdb_ci_spkg"},
{"serial_number":"L3CD257","name":"IBM-T42-DLG","className":"cmdb_ci_computer","install_status":null,"key":"L3CD257:IBM-T42-DLG:cmdb_ci_computer"},
{"serial_number":null,"name":"Windows XP Hotfix (SP2) Q817606","className":"cmdb_ci_spkg","install_status":"1","key":"null:Windows XP Hotfix (SP2) Q817606:cmdb_ci_spkg"},
{"serial_number":null,"name":"WeatherBug","className":"cmdb_ci_spkg","install_status":"1","key":"null:WeatherBug:cmdb_ci_spkg"},
{"serial_number":null,"name":"EFOWEB","className":"cmdb_ci_computer","install_status":"1","key":"null:EFOWEB:cmdb_ci_computer"},
{"serial_number":null,"name":"MailServerUS","className":"cmdb_ci_server","install_status":"1","key":"null:MailServerUS:cmdb_ci_server"},
{"serial_number":null,"name":"WEBSERVER","className":"cmdb_ci_computer","install_status":"1","key":"null:WEBSERVER:cmdb_ci_computer"},
{"serial_number":null,"name":"FileServerFloor2","className":"cmdb_ci_server","install_status":"1","key":"null:FileServerFloor2:cmdb_ci_server"},
{"serial_number":"L3BB911","name":"*JEMPLOYEE-IBM","className":"cmdb_ci_computer","install_status":"1","key":"L3BB911:*JEMPLOYEE-IBM:cmdb_ci_computer"},
{"serial_number":null,"name":"Sales Force Automation","className":"cmdb_ci_service","install_status":"1","key":"null:Sales Force Automation:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Controlling","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Controlling:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Financial Accounting","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Financial Accounting:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Human Resources","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Human Resources:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Materials Management","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Materials Management:cmdb_ci_service"},
{"serial_number":null,"name":"SAP Sales and Distribution","className":"cmdb_ci_service","install_status":"1","key":"null:SAP Sales and Distribution:cmdb_ci_service"},
{"serial_number":"cx320-4001-21a","name":"nyc rac nas200","className":"cmdb_ci_msd","install_status":"1","key":"cx320-4001-21a:nyc rac nas200:cmdb_ci_msd"},
{"serial_number":null,"name":"EXCH-SD-05","className":"cmdb_ci_email_server","install_status":"1","key":"null:EXCH-SD-05:cmdb_ci_email_server"}
]
If you look careful you will see that there is a duplicate of the following entry:
{"serial_number":null,"name":"Sales Force Automation","className":"cmdb_ci_service","install_status":"1","key":"null:Sales Force Automation:cmdb_ci_service"},
{"serial_number":null,"name":"Sales Force Automation","className":"cmdb_ci_service","install_status":"1","key":"null:Sales Force Automation:cmdb_ci_service"},
and it has been removed.
Okay, so let's refactor our new uniqueObjectList function a bit.
var incidentRecords = new GlideRecord('incident');
incidentRecords.addNotNullQuery('cmdb_ci');
incidentRecords.addActiveQuery();
incidentRecords.query();
var cmdbList = [];
// The following looping code is a GlideRecord inside of a GlideRecord.
// This is normally a BAD way of doing this, but I want
// to make SURE I have duplicates in the Object List!
while (incidentRecords.next()) {
var ciRecords = new GlideRecord('cmdb_ci');
if (ciRecords.get('sys_id', incidentRecords.getValue('cmdb_ci'))) {
cmdb_ci = {};
cmdb_ci.serial_number = ciRecords.getValue('serial_number');
cmdb_ci.name = ciRecords.getValue('name');
cmdb_ci.className = ciRecords.getValue('sys_class_name');
cmdb_ci.install_status = ciRecords.getValue('install_status');
cmdb_ci.key = cmdb_ci.serial_number + ':' + cmdb_ci.name + ':' + cmdb_ci.className;
cmdbList.push(cmdb_ci);
}
}
gs.info('BEFORE: {0}\n{1}', [cmdbList.length, JSON.stringify(cmdbList)]);
cmdbList = uniqueObjectList(cmdbList, 'key');
gs.info('AFTER: {0}\n{1}', [cmdbList.length, JSON.stringify(cmdbList)]);
function uniqueObjectList (dedupList, field) {
for (var i = 0; i < dedupList.length; i++) {
for (var j = i + 1; j < dedupList.length; j++) {
if (dedupList[j][field] == dedupList[i][field]) {
dedupList.splice(j, 1);
--j;
}
}
}
return dedupList;
}
The results should be exactly the same.
You might want to put this into a Script Include function library (utils) of some sort for ease of use, and to minimize any maintenance. Just a thought.
Despite the disdain I run into from other programmers working with "real" languages (i.e. C#, Java), I feel JavaScript can be just as powerful in its own way! And lest you sniff at that comment, let me point out that I have done C#/.Net development since .Net 0.9 Beta, and I took a class on OOP from Bjarne Stroustrup himself when he had just started touring to talk about C++! Go Ada! Alas, I date myself. Each language has it's uses!
Enjoy!
Steven Bell.
If you find this article helps you, don't forget to log in and mark it as "Helpful"!
Originally published on: 08-18-2016 09:51 PM
I updated the code and brought the article into alignment with my new formatting standard.
- 2,754 Views
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.