Sum The Differences Between Array Elements

It’s always a good idea to continue to ‘sharpen the axe’ and keep your JavaScript algorithmic muscles in shape.

In this post we’re going to take on a coding challenge where the objective is to create a function that accepts an array of integers and sums the difference between the consecutive pairs in the array.

The rules

Here are the rules:

  • The differences should be calculated in descending order.
  • If a given array is empty, or the array has only a single element, the sum result should be 0.
  • The solution should also account for negative integers in an array e.g. [-4, 2, -6].

The logic

Let’s first break this down with an example. When the function takes in the following array:

[2, 1, 10];

It should output 9. Why? The calculation should be performed in descending order, so the array should be sorted as follows:

[10, 2, 1];

The differences between the consecutive pairs would then be calculated like so:

(10 - 2) + (2 - 1) = 8 + 1 = 9

A possible solution

At this point, feel free to attempt to solve this problem on your own, then come back to compare your solution.

There are essentially three steps to solving this problem:

  1. Sort the given array in descending order.
  2. Loop through the array and calculate the difference between each pair of elements.
  3. Sum all of the differences.

Sort the array

First, let’s declare a function sumDifferences (or whatever you’d like to call it) that takes in an array of integers:

function sumDifferences(arr) {}

The first task is to sort the array. We can use JavaScript’s sort() method to achieve this:

function sumDifferences(arr) {
  // Sort array in descending order
  const sortedArr = arr.sort((a, b) => b - a);
}

Above I call sort() on the given array and use b - a to sort the values in descending order and store them in a new array called sortedArr.

For ascending order, you can use a - b. For more information on how sort() works, take a look at the MDN documentation.

Loop through the elements

Now we need to loop through this sorted array and figure out the differences between each consecutive pair of elements. We also need to keep a track of the differences, so let’s set that up too:

function sumDifferences(arr) {
  // Sort array in descending order
  const sortedArr = arr.sort((a, b) => b - a);
  // Initialise difference tracker
  let sum = 0;
  // Loop through sorted array
  for (let i = 0; i < sortedArr.length - 1; i++) {}
}

We initialise a variable sum to 0 - we’ll add each of the differences to this sum as we go and the function will ultimately return it at the end.

Here I’m using a for loop to iterate through the sorted array items. Notice that I specify the total number of iterations using sortedArr.length - 1 - more on this shortly.

Calculate the differences

Let’s picture the first iteration. Given the array [10, 2, 1] , the first element (element 0) will be 10 and the second element (element 1) will be 2. We want to take 2 away from 10 to result in 8, so we can calculate the different between these as follows:

sortedArr[i] - sortedArr[i + 1];

However, what happens when we reach the last element in the array (in this case 1)? There won’t be any more elements to compare with. This is why I set the total number of iterations to be one element less than the total length of the array with sortedArr.length - 1. In other words, the loop will end at the penultimate element (in this case 2, comparing 2 with 1).

Sum the differences

Now we just need to take the result (8) and add it to the sum. We can use the shorthand syntax +=:

sum += sortedArr[i] - sortedArr[i + 1];

Finally, the function simply needs to return the sum - remember to do this outside of the loop:

function sumDifferences(arr) {
  // Sort array in descending order
  const sortedArr = arr.sort((a, b) => b - a);
  // Initialise difference tracker
  let sum = 0;
  // Loop through sorted array
  for (let i = 0; i < sortedArr.length - 1; i++) {
    // Calculate difference between consecutive pairs
    sum += sortedArr[i] - sortedArr[i + 1];
  }
  // Return total
  return sum;
}

It’s important to note that this solution also works for negative integers.

Alternative solutions

As with anything in programming, there are many different ways to solve the same problem. Some solutions are more efficient but less readable, and some are more verbose but less scalable.

For example, the following solution elegantly chains together three different higher-order array functions - sort, map and reduce - to generate a single result:

const sumDifferences = (arr) =>
  arr
    .sort((a, b) => b - a)
    .map((el, idx) => el - arr[idx + 1] || 0)
    .reduce((a, b) => a + b, 0);

sort is used in the same way, bubbling items up and down in descending order. map also works in a similar way by subtracting the consecutive element (accessed with arr[idx + 1]) from the current element. If the consecutive element doesn’t exist (i.e. we’ve hit the end of the array) it returns 0 instead. Finally, reduce iterates through the array of differences and adds them all together.

This next solution takes things even further:

function sumDifferences(arr) {
  return arr.length > 1 ? Math.max(...arr) - Math.min(...arr) : 0;
}

Rather than sorting the array items and looping through them, it uses Math.max() and Math.min() to calculate the highest and lowest integers in the array respectively. Then it simply takes the lowest number from the highest number to give the overall difference. Finally, this logic is wrapped in a ternary check where it only executes if there is more than one element in the array, otherwise it returns 0.

This can be refactored even further into a single line using arrow function syntax:

const sumDifferences = (arr) =>
  arr.length <= 1 ? 0 : Math.max(...arr) - Math.min(...arr);

Conclusion

There we have it: multiple ways to sum the differences between consecutive array items.

How did you do? Did you come up with a different solution? Let me know on Twitter.