0

I have an array of objects

const arrayOfObjects = [{firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''},{firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}];

I need to return an array of keys that are empty in all of the objects in the array. So for the above example, it would return ['firstKey', 'fourthKey'] but not 'secondKey', because it is only empty in one of the objects.

I have found a lot of examples (like one below) that return boolean but having trouble finding a way to return the actual empty keys. Thanks

const isEmpty = Object.values(object).every(x => (x === ''));
1
  • I guess, you just need a filter over here. Rather than making it complicated by using every and then x === '' Commented May 6, 2021 at 19:47

4 Answers 4

2

Get the keys from the 1st object in the array, and then filter them by checking for each key that it's empty in all objects with Array.every():

const checkAllEmpty = arr =>
  Object.keys(arr[0] ?? {}) // get the keys from the 1st object or use an empty object as fallback
    .filter(key => arr.every(o => o[key] === '')) // filter the keys by checking each object in the array

const arr = [{firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''},{firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}]

const result = checkAllEmpty(arr)

console.log(result)

Old answer:

Reduce the array to a Map, and count how many times a key is empty. Convert the Map to an an array of [key, value] using Array.from(), filter all the entries that have a value that is less then the array's length, and map to an array of keys:

const arr = [{firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''},{firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}]

const result = Array.from(arr.reduce((acc, obj) => {
    Object.entries(obj)
      .forEach(([k, v]) => {
        if (v === '') acc.set(k, (acc.get(k) ?? 0) + 1)
      })

    return acc
  }, new Map))
  .filter(([, v]) => v === arr.length)
  .map(([k]) => k)

console.log(result)

Sign up to request clarification or add additional context in comments.

1 Comment

@Marky1298 - I've updated the answer with a better solution.
1

Array.prototype.every returns true when every item satisfies the predicate you pass as a callback. What you actually need is Array.prototype.filter:

const arrayOfObjects = [{firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''},{firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}];

const deduplicate = arr => [...new Set(arr)];

const isEmpty = arrayOfObjects.flatMap(x => Object.entries(x)).filter(([, value]) => !value).map(([key]) => key);

const uniqueIsEmpty = deduplicate(isEmpty);

console.log(uniqueIsEmpty);

2 Comments

Thanks, this is close, I would just need to make each key unique and only key (not value) in return. Thanks, will work with this
Yes, thanks "it would return [firstKey, fourthKey] but not secondKey, because it is only empty in one of the objects"
1

This version will assume undefined keys are also "empty", in case the objects in your array have inconsistent keys.

const arr = [
    {firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''}, 
    {firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}
];

const isEmpty = v => v == '';

const result = Array.from(
    arr.reduce((acc, obj) => 
        Object.entries(obj).reduce((_, [k, v]) => 
            acc.set(k, acc.has(k) ? acc.get(k) && isEmpty(v) : isEmpty(v))
        , null)
    , new Map())
).filter(([, v]) => v).map(([k]) => k);

console.log(result)

Comments

0
const arrayOfObjects = [{firstKey: '', secondKey: 'someValue', thirdkey: 'someValue', fourthKey: ''},{firstKey: '', secondKey: '', thirdkey: 'someValue', fourthKey: ''}];
let k = []
arrayOfObjects.map(obj => { k = k.concat(k, Object.keys(obj))})
let arr = [...new Set(k)];
console.log(arr);
  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.