Check if each value of a key in an object array are equal or null

Viewed 854

I need to check if each value of a specific key in an object array are equal or null.

So far I have got this method

const allEqual = (arr, key) =>
  arr.every((v) => v[key] === arr[0][key] || v[key] === null);

Which takes in a array and key and checks if the key matches based on Array.prototype.every().

Whilst this works great if there are no null values, when there is a null value it doesn't.

const allEqual = (arr, key) =>
  arr.every((v) => v[key] === arr[0][key] || v[key] === null);

let example1 = [
  {
    test: "foo",
  },
  {
    test: "foo",
  },
  {
    test: "foo",
  },
];
//This works
console.log(allEqual(example1, "test"));
let example2 = [
  {
    test: null,
  },
  {
    test: "foo",
  },
  {
    test: "foo",
  },
]; 

//This DOES Not work
console.log(allEqual(example2, "test"));

//This works
let example3 = [
  {
    test: "foo",
  },
  {
    test: "foo",
  },
  {
    test: null,
  },
];
console.log(allEqual(example3, "test"));

1 Answers

The problem is that your null is the first entry, and you're using the first entry as the check for identical-ness.

You need to find and remember the first non-null entry to use for subsequent checks on non-null entries. You can still do it in one pass if you close over a variable to set:

const allEqual = (arr, key) => {
    let firstNonNull = null;
    return arr.every((v) => {
        const value = v[key];
        if (value === null) {
            return true;
        }
        if (firstNonNull === null) {
            firstNonNull = value;
            return true;
        }
        return value === firstNonNull;
    });
};

Live Example:

const allEqual = (arr, key) => {
    let firstNonNull = null;
    return arr.every((v) => {
        const value = v[key];
        if (value === null) {
            return true;
        }
        if (firstNonNull === null) {
            firstNonNull = value;
            return true;
        }
        return value === firstNonNull;
    });
};

let example = [
    {
        test: null,
    },
    {
        test: "foo",
    },
    {
        test: "foo",
    },
];
console.log(allEqual(example, "test")); // true

let counterExample = [
    {
        test: null,
    },
    {
        test: "foo",
    },
    {
        test: "bar",
    },
];
console.log(allEqual(counterExample, "test"));

That can be made more concise; it's verbose above for clarity.

Related