Home > Mobile >  How to remove nulls from array and a linked array whilst preserving order
How to remove nulls from array and a linked array whilst preserving order

Time:05-05

I know how to remove null values from a single array using filters:

y = [7, 8, 9, null, null, 3, 4, null, 1]

y.filter(Number)
// [7, 8, 9, 3, 4, 1]

However, I'd also like to remove all those of an associated array whilst preserving the order of elements in both arrays.

Say I have,

x = [42, 60, 70, 100, 200, 400, 500, 900, 1000]

y = [7, 8, 9, null, null, 3, 4, null, 1]

where an element of x is associated with y, i.e., if y[94] is null (which should be removed), x[94] should be removed too.

The end result should be:

x = [42, 60, 70, 400, 500, 1000]

y = [7, 8, 9, 3, 4, 1]

I've tried finding what elements are null and then manually looping through them to remove the nulls, but I'd like a more elegant solution.

Cheers!

CodePudding user response:

You can simply filter() the arrays against each other by index as provided as the second parameter in the callback.

const x = [42, 60, 70, 100, 200, 400, 500, 900, 1000]
const y = [7, 8, 9, null, null, 3, 4, null, 1]

const xFiltered = x.filter((n, i) => n !== null && y[i] !== null);
const yFiltered = y.filter((n, i) => n !== null && x[i] !== null);

console.log(...xFiltered)
console.log(...yFiltered)

CodePudding user response:

The provided above answer from @pilchard will work, but

Solution 1 (Declarative)

More declarative solution can be achieved with combination of lodash zip, array filter and lodash unzip.

import { zip, unzip } from 'lodash';

const x = [42, 60, 70, 100, 200, 400, 500, 900, 1000];
const y = [7, 8, 9, null, null, 3, 4, null, 1];

const zipped = zip(x, y).filter(([xNum, yNum]) => yNum !== null);
const [newX, newY] = unzip(zipped);

CodeSandbox

⚠️ it will be a bit less performant though

Solution 2 (More performant)

In @pilchard's case we do two array iterations, in case of solution 1 we do three iterations. But we can actually do in a single iteration with reduce.

const x = [42, 60, 70, 100, 200, 400, 500, 900, 1000];
const y = [7, 8, 9, null, null, 3, 4, null, 1];

const [newX, newY] = x.reduce((acc, xNum, xIndex) => {
    const yNum = y[xIndex];

    if (yNum === null) return acc;

    acc[0].push(xNum);
    acc[1].push(yNum);

    return acc;
}, [[], []]);
  • Related