10 JavaScript Array Utils
Tags: javascript, utilities
Published: 2019-11-04 15:14:48


10 utility functions *with no dependencies*, to borrow and use for both Node.js and Browser applications to work with Array. Each function has a snippet block and executable demo with a unit tests.

## chunk

Split an array into chunks. If array can't be split equally based on the given size, the last chunk will be the remaining elements.

```javascript
/*
 * chunk
 * @param {Array} array - List of elements
 * @param {Number} size - Length of each chunk to group
 * @return {Array} Returns list of grouped chunks
 */
function chunk(array, size = 1) {
  return [array.slice(0, size)].concat(chunk(array.slice(size), size));
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;
const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function chunk(array, size = 1) {
    return isArrayWithLength(array) ? [array.slice(0, size)].concat(chunk(array.slice(size), size)) : [];
}

const actual = chunk(['one', 'two', 'three', 'four', 'five'], 2);
const expected = [['one', 'two'], ['three', 'four'], ['five']];

assert.deepEqual(actual, expected);
assert.lengthOf(actual, 3);

const emptyList = [];

assert.deepEqual(chunk([], 2), emptyList);
assert.deepEqual(chunk({}, 2), emptyList);
assert.deepEqual(chunk(null, 2), emptyList);
{% endrunkit %}

---

## compact

Compact is a falsy bouncer that returns a new copy with 
all falsey values: `false`, `null`, `0`, `""`, `undefined`, and `NaN` removed.

```javascript
/*
 * compact
 * @param {Array} array - A list of elements to compact
 * @return {Array} Returns a filtered values 
 */
function compact(array) {
  return array.filter(Boolean);
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;
const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function compact(array) {
    return isArrayWithLength(array) ? array.filter(Boolean) : [];
}

const actual = compact([15, 06, false, 8, '', 7, 'em', undefined]);
const expected = [15, 06, 8, 7, 'em'];

assert.deepEqual(actual, expected);
assert.lengthOf(actual, 5);
{% endrunkit %}

---

## merge

Merges any additional values (args) to the first given input/array.

```javascript
/*
 * merge
 * @param {Array} array - Main list to link to
 * @param {...*} args - The values to chain
 * @return {Array} Returns a series or chainable values
 */
function merge(array, ...args) {
  return [...array, ...args.flat()] :;
}
```

### Demo

*⚠️ please select a higher Node version (10+) before you execute the code below*

{% runkit %}
const chai = require("chai");
const assert = chai.assert;

const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function merge(array, ...args) {
    return isArrayWithLength(array) ? [...array, ...args.flat()] : [];
}

const one = ['one'];
const actual = merge(one, 'two', ['three'], [['four']]);
const expected = ['one', 'two', 'three', ['four']];

assert.deepEqual(actual, expected);
assert.lengthOf(actual, 4);
{% endrunkit %}

---

## last

Get the last element from array.

```javascript
/*
 * last
 * @param {Array} array
 * @return {String} Returns last element in array
 */
function last(array) {
  return array[array.length - 1];
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;
const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function last(array) {
    return isArrayWithLength(array) ? array[array.length - 1] : [];
}

const actual = last(['one', 'two', 'three', 'four']);
const expected = 'four';

assert.deepEqual(actual, expected);
assert.isString(expected);
{% endrunkit %}

---

## uniq

Creates a duplicate-free version from the given input-array

```javascript
/*
 * uniq
 * @param {Array} array - List of elements
 * @param {Boolean} [sort=false] - optional flag to sort
 * @return {Array} Returns uniq values list
 */
function uniq(array, sort = false) {
  return sort ? [...new Set(array)].sort() : [...new Set(array)];
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;
const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function uniq(array, sort = false) {
    return isArrayWithLength(array) ? (sort ? [...new Set(array)].sort() : [...new Set(array)]) : [];
}

const duplicatedValues = ['b', 'a', 'c', 'd', 'a', 'c', 'b'];
const actual = uniq(duplicatedValues);
const expected = ['b', 'a', 'c', 'd'];
const expectedOrder = ['a', 'b', 'c', 'd'];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 4);
assert.deepEqual(uniq(duplicatedValues, true), expectedOrder);
{% endrunkit %}

---

## range

Creates a set of values (`keys()` method - keys for each index in the array) with a beginning (`0`) and an end (`size` param)

```javascript
/*
 * range
 * @param {Number} size
 * @return {Array} Returns a list of generated keys
 */
function range(size) {
  return [...Array(size).keys()];
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;

function range(size) {
    return size ? [...Array(size).keys()] : [];
}

const actual = range(11);
const expected = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 11);
{% endrunkit %}

---

## intersection

Finds all values that are the intersection/included in all the given arrays/args and creates a list from the result.

```javascript
/*
 * intersection
 * @param {...*} args - List of arrays
 * @return {Array} Returns a list of unique values
 */
function intersection(...args) {
  const [ first, ...rest ] = args;
  return first.filter(item => rest.flat().includes(item));
}
```

### Demo

*⚠️ please select a higher Node version (10+) before you execute the code below*

{% runkit %}
const chai = require("chai");
const assert = chai.assert;

function intersection(...args) {
    const [ first, ...rest ] = args;
    return first.filter(item => rest.flat().includes(item))
}

const actual = intersection(['a', 'b', 'c'], ['b', 'c'], ['b', 'c', 'd', 'e']);
const expected = ['b', 'c'];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 2);
assert.include(expected, 'b');
assert.include(expected, 'c');
{% endrunkit %}

---

## diff

Creates a list of values from array that are not present in other arrays/args. Result are determined by the first input

```javascript
/*
 * diff
 * @param {...*} args - List of arrays
 * @return {Array} Returns result of excluded values
 */
function diff(...args) {
  const [ first, ...rest ] = args;
  return first.filter(item => !rest.flat().includes(item));
}
```

### Demo

*⚠️ please select a higher Node version (10+) before you execute the code below*

{% runkit %}
const chai = require("chai");
const assert = chai.assert;

function diff(...args) {
    const [ first, ...rest ] = args;
    return first.filter(item => !rest.flat().includes(item));
}

const actual = diff(['a', 'b', 'c'], ['b', 'c'], ['b', 'c', 'd', 'e']);
const expected = ['a'];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 1);
assert.include(expected, 'a');
{% endrunkit %}

---

## allBut

Excludes specified values from the given array

```javascript
/*
 * allBut
 * @param {Array} list - Array of elements
 * @param {...*} args - Values to exclude
 * @return {Array} Returns filtered list
 */
function allBut(list, ...args) {
  return list.filter((value) => !args.includes(value));
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;

function allBut(list, ...args) {
    return list.filter((value) => !args.includes(value));
}

const actual = allBut(['first', 'second', 'third', 'fourth', 'fifth'], 'fourth');
const expected = ['first', 'second', 'third', 'fifth'];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 4);
assert.notInclude(expected, 'fourth');
{% endrunkit %}

---

## allButFirst

Creates a copy without the first element in array by [destructuring](https://dev.to/_elmahdim/destructuring-in-javascript-87n) all elements except the first one. If the given list has only one item it returns an empty array `[]`

```javascript
/*
 * allButFirst
 * @param {Array} array - List of elements
 * @return {Array} Returns filtered list
 */
function allButFirst([, ...rest]) {
  return rest;
}
```

### Demo

{% runkit %}
const chai = require("chai");
const assert = chai.assert;
const isArrayWithLength = (array) => Boolean(Array.isArray(array) && array.length);

function allButFirst(list) {
 if (isArrayWithLength(list)) {
     const [, ...rest] = list;
     return rest;
 }
 return [];
}

const actual = allButFirst(['first', 'second', 'third', 'fourth', 'fifth']);
const expected = ['second', 'third', 'fourth', 'fifth'];

assert.deepEqual(actual, expected);
assert.lengthOf(expected, 4);
assert.notInclude(expected, 'first');
{% endrunkit %}


Some of these functions are inspired by popular libraries like [underscore](https://underscorejs.org) and [lodash](https://lodash.com) which I highly recommend to use for more complex operations and working with data types as well.