Ron
Ron

Reputation: 6723

How to get additions and deletions between two arrays in Node.js?

I have 2 arrays that change once in a while. I want to compare them and get the additions & deletions between the first, source array and the second array.

Additions/deletions can occur at the middle of the array (not necessarily at the edges).

For example, from these arrays:

Array 1
Item A | Item B | Item C | Item D | Item E

Array 2
Item A | Item Z | Item C | Item D | Item E

I would like to get the following output: - Item B was removed - Item Z was added

What is the best way to deal with this issue?

Upvotes: 1

Views: 628

Answers (3)

Alex Lomia
Alex Lomia

Reputation: 7235

This can be accomplished in linear time.

When we have unique arrays (simpler algorithm)

const getDifferenceUnique = (arrayA, arrayB) => {
  const valuesByFrequencies = (accumulator, value) => ({
    ...accumulator,
    [value]: true,
  });

  const dictionaryA = arrayA.reduce(valuesByFrequencies, {});
  const dictionaryB = arrayB.reduce(valuesByFrequencies, {});

  return {
    // get only those values from the `arrayA` that AREN'T present in the 
    // `arrayB`. This will get us an array containing the REMOVED items only. 
    deletions: arrayA.filter((value) => !dictionaryB[value]),
    // get only those values from the `arrayB` that AREN'T present in the 
    // `arrayA`. This will get us an array containing the ADDED items only. 
    additions: arrayB.filter((value) => !dictionaryA[value])
  }
};

const { deletions, additions } = getDifferenceUnique(['1', '2'], ['2', '3']);

console.log('Deletions', deletions);
console.log('Additions', additions);

When we have non-unique arrays

const getDifference = (arrayA, arrayB) => {
  const valuesByFrequencies = (accumulator, value) => ({
    ...accumulator,
    [value]: accumulator[value] ? accumulator[value] + 1 : 1
  });

  const dictionaryA = arrayA.reduce(valuesByFrequencies, {});
  const dictionaryB = arrayB.reduce(valuesByFrequencies, {});

  const createMapValuesByFrequencies = (dictionary) => ([key, frequency]) => {
    const difference = (dictionary[key] || 0) - frequency;

    return difference < 0 ? [key, difference] : null;
  }
  const filterNulls = (value) => value;
  const getValuesByFrequencies = (accumulator, [key, frequency]) => [
    ...accumulator,
    ...key.repeat(Math.abs(frequency)).split('')
  ];

  return {
    deletions: Object.entries(dictionaryA)
      .map(createMapValuesByFrequencies(dictionaryB))
      .filter(filterNulls)
      .reduce(getValuesByFrequencies, []),
    additions: Object.entries(dictionaryB)
      .map(createMapValuesByFrequencies(dictionaryA))
      .filter(filterNulls)
      .reduce(getValuesByFrequencies, [])
  };
};

const { deletions, additions } = getDifference(['1', '2', '2', '2', '2'], ['2', '3', '3']);

console.log('Deletions', deletions);
console.log('Additions', additions);

Upvotes: 0

arturocandela
arturocandela

Reputation: 1

If the elements have random positions, the only think you can do is traverse the array in order to get sure of what elements are add or removed or you can use the underscore lib it has a package for node, too

the function is:

_.difference(array, *others) 

Regards

Upvotes: -1

rajeshpanwar
rajeshpanwar

Reputation: 1233

If the item type is string, then follow this

var getAddedorRemovedItem = function (sourceArray1, sourceArray2) {
    var added = [], removed = [];
    sourceArray1.forEach(function(item){
        if (sourceArray2.indexOf(item) == -1) {
            removed.push(item);
        }
    });
    sourceArray2.forEach(function (item) {
        if (sourceArray1.indexOf(item) == -1) {
            added.push(item);
        }
   });

// here added array contain all new added item and removed contain all removed item;

// do acc. to whatever you want to get outpur
}

Upvotes: 6

Related Questions