Languages
[Edit]
EN

JavaScript - detect array items changes (added, updated, removed, unchanged)

10 points
Created by:
Anisha-Kidd
652

In this short article, we would like to show how to detect changes in an array in JavaScript.

Added, updated, removed and unchanged items detection in array.
Added, updated, removed and unchanged items detection in array.

As changes, we understand to detect what item was added, updated, removed or unchanged.

Note: in the below example, it is necessary to indicate own functions that:

  • gets array item key - getKey(item) in the code,
  • compares array items to see difference - compareItems(a, b) in the code.

Quick solution:

// ONLINE-RUNNER:browser;

function mapItems(items, getKey) {
  	var map = {};
  	for (var i = 0; i < items.length; ++i) {
      	var item = items[i];
      	var key = getKey(item);
      	if (key in items) {
            throw new Error('Item key is duplicated (' + key + ').');
        }
      	map[key] = item;
    }
  	return map;
}

function detectChanges(prevItems, nextItems, getKey, compareItems) {
    var mappedItems = mapItems(prevItems, getKey);
    var detectedChanges = {
        addedItems: [],
        updatedItems: [],
        removedItems: [],
        unchangedItems: []
    };
    for (var i = 0; i < nextItems.length; ++i) {
        var nextItem = nextItems[i];
      	var itemKey = getKey(nextItem);
        if (itemKey in mappedItems) {
            var prevItem = mappedItems[itemKey];
            if (delete mappedItems[itemKey] && compareItems(prevItem, nextItem)) {
                detectedChanges.unchangedItems.push(nextItem);
            } else {
              	detectedChanges.updatedItems.push(nextItem);
            }
        } else {
            detectedChanges.addedItems.push(nextItem);
        }
    }
    for (var itemKey in mappedItems) {
      	if (itemKey in mappedItems) {
            detectedChanges.removedItems.push(mappedItems[itemKey]);
        }
    }
    return detectedChanges;
}


// Usage example:

var prevItems = [
    {name: 'John',  value: 32},  // Unchanged
    {name: 'Kate',  value: 21},  // Updated
    {name: 'Matt',  value: 26},  // Removed
    {name: 'Greg',  value: 24}   // Unchanged
];

var nextItems = [
    {name: 'John',  value: 32},  // Unchanged
    {name: 'Kate',  value: 25},  // Updated
    {name: 'Chris', value: 40},  // Added
    {name: 'Greg',  value: 24}   // Unchanged
];

var getKey = function(item) {
    return item.name;
};

var compareItems = function(a, b) {
    return a.name === b.name && a.value === b.value;
};

var detectedChanges = detectChanges(prevItems, nextItems, getKey, compareItems);

console.log('Added items: '     + JSON.stringify(detectedChanges.addedItems,     null, 4));
console.log('Updated items: '   + JSON.stringify(detectedChanges.updatedItems,   null, 4));
console.log('Removed items: '   + JSON.stringify(detectedChanges.removedItems,   null, 4));
console.log('Unchanged items: ' + JSON.stringify(detectedChanges.unchangedItems, null, 4));

 

ES6+ solution

// ONLINE-RUNNER:browser;

const mapItems = (items, getKey) => {
  	const map = {};
  	for (const item of items) {
      	const key = getKey(item);
      	if (key in items) {
            throw new Error('Item key is duplicated (' + key + ').');
        }
      	map[key] = item;
    }
  	return map;
}

const detectChanges = (prevItems, nextItems, getKey, compareItems) => {
    const mappedItems = mapItems(prevItems, getKey);
    const addedItems = [];
    const updatedItems = [];
    const removedItems = [];
    const unchangedItems = [];
    for (const nextItem of nextItems) {
      	const itemKey = getKey(nextItem);
        if (itemKey in mappedItems) {
            const prevItem = mappedItems[itemKey];
            if (delete mappedItems[itemKey] && compareItems(prevItem, nextItem)) {
                unchangedItems.push(nextItem);
            } else {
              	updatedItems.push(nextItem);
            }
        } else {
            addedItems.push(nextItem);
        }
    }
    for (const itemKey in mappedItems) {
      	if (itemKey in mappedItems) {
            removedItems.push(mappedItems[itemKey]);
        }
    }
    return {addedItems, updatedItems, removedItems, unchangedItems};
}


// Usage example:

const prevItems = [
    {name: 'John',  value: 32},  // Unchanged
    {name: 'Kate',  value: 21},  // Updated
    {name: 'Matt',  value: 26},  // Removed
    {name: 'Greg',  value: 24}   // Unchanged
];

const nextItems = [
    {name: 'John',  value: 32},  // Unchanged
    {name: 'Kate',  value: 25},  // Updated
    {name: 'Chris', value: 40},  // Added
    {name: 'Greg',  value: 24}   // Unchanged
];

const getKey = (item) => item.name;
const compareItems = (a, b) => a.name === b.name && a.value === b.value;

const detectedChanges = detectChanges(prevItems, nextItems, getKey, compareItems);

console.log('Added items: '     + JSON.stringify(detectedChanges.addedItems,     null, 4));
console.log('Updated items: '   + JSON.stringify(detectedChanges.updatedItems,   null, 4));
console.log('Removed items: '   + JSON.stringify(detectedChanges.removedItems,   null, 4));
console.log('Unchanged items: ' + JSON.stringify(detectedChanges.unchangedItems, null, 4));

 

Alternative titles

  1. JavaScript - get the difference between two arrays
  2. JavaScript - arrays diff
  3. JavaScript - compare arrays (added, updated, removed, unchanged)
Donate to Dirask
Our content is created by volunteers - like Wikipedia. If you think, the things we do are good, donate us. Thanks!
Join to our subscribers to be up to date with content, news and offers.
Native Advertising
🚀
Get your tech brand or product in front of software developers.
For more information Contact us
Dirask - we help you to
solve coding problems.
Ask question.

❤️💻 🙂

Join