Loood89
Loood89

Reputation: 13

Filter out array of objects on same key being empty ("")

I have an array of objects that needs to be filtered. It looks something like this:

        let array = [
            {
                "id": "",
                "first_name": "Kary",
                "last_name": "Thorndale",
                "email": "kthorndale1@nifty.com",
                "gender": "Female",
                "ip_address": "172.152.36.109"
            },
            {
                "id": "",
                "first_name": "Westley",
                "last_name": "Emmott",
                "email": "wemmott2@cisco.com",
                "gender": "Male",
                "ip_address": "104.62.125.170"
            },
            {
                "id": "",
                "first_name": "Gavrielle",
                "last_name": "Danihel",
                "email": "gdanihel3@yandex.ru",
                "gender": "Female",
                "ip_address": "98.98.209.17"
            }
    ];

I have only one condition - if key in all objects is empty remove it from all objects.

I can use jQuery or loDash if it is faster or there is any need for it.

There shouldn't be more than 15-20 objects in array and there will be up to 15 arrays like this that needs to go through filter.

Upvotes: 1

Views: 77

Answers (3)

Akrion
Akrion

Reputation: 18525

Here is concise solution with lodash.

let data = [ { "id": "", "first_name": "Kary", "last_name": "Thorndale", "email": "kthorndale1@nifty.com", "gender": "Female", "ip_address": "172.152.36.109" }, { "id": "", "first_name": "Westley", "last_name": "Emmott", "email": "wemmott2@cisco.com", "gender": "Male", "ip_address": "104.62.125.170" }, { "id": "", "first_name": "Gavrielle", "last_name": "Danihel", "email": "gdanihel3@yandex.ru", "gender": "Female", "ip_address": "98.98.209.17" } ];

const mrg = (r,c) => _.mergeWith(r,c, (o,s) => _.isEmpty(o) ? s : o)

const result = _.map(data, x => 
  _.omit(x,_.chain(data).reduce(mrg).pickBy(_.isEmpty).keys().value()))

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Main idea here is to merge all objects to one since that way we would know right away which key is empty everywhere. We do this with the mrg function which inside uses mergeWith to provide a customizer. Main purpose of that function is to make sure we merge on a non empty value.

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386868

You could count the empty values for the same key and map new objects without all emty properties.

var array = [{ id: "", first_name: "Kary", last_name: "Thorndale", email: "kthorndale1@nifty.com", gender: "Female", ip_address: "172.152.36.109" }, { id: "", first_name: "Westley", last_name: "Emmott", email: "wemmott2@cisco.com", gender: "Male", ip_address: "104.62.125.170" }, { id: "", first_name: "Gavrielle", last_name: "Danihel", email: "gdanihel3@yandex.ru", gender: "Female", ip_address: "98.98.209.17" }],
    keys = Array
        .from(array.reduce((m, o) => {
            Object.entries(o).forEach(([k, v]) => m.set(k, (m.get(k) || 0) + +!!v));
            return m;
        }, new Map))
        .filter(({ 1: v }) => v)
        .map(([k]) => k),
    result = array.map(o => Object.assign(...keys.map(k => ({ [k]: o[k] }))));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

A slightly better version with a Set

var array = [{ id: "", first_name: "Kary", last_name: "Thorndale", email: "kthorndale1@nifty.com", gender: "Female", ip_address: "172.152.36.109" }, { id: "", first_name: "Westley", last_name: "Emmott", email: "wemmott2@cisco.com", gender: "Male", ip_address: "104.62.125.170" }, { id: "", first_name: "Gavrielle", last_name: "Danihel", email: "gdanihel3@yandex.ru", gender: "Female", ip_address: "98.98.209.17" }],
    keys = Array.from(
        array.reduce(
            (s, o) => Object.entries(o).reduce((t, [k, v]) => v ? t.add(k) : t, s),
            new Set
        )
    ),
    result = array.map(o => Object.assign(...keys.map(k => ({ [k]: o[k] }))));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

brk
brk

Reputation: 50346

You can use findIndex to get check if there exist empty string as a value for that specific key. If it is -1 then that key have no empty string as value.

If it is not greater than -1 then you can use map to return a new array and inside the callback function create a new object and set the key and it's value

let array = [{
    "id": "",
    "first_name": "Kary",
    "last_name": "Thorndale",
    "email": "kthorndale1@nifty.com",
    "gender": "Female",
    "ip_address": "172.152.36.109"
  },
  {
    "id": "",
    "first_name": "Westley",
    "last_name": "Emmott",
    "email": "wemmott2@cisco.com",
    "gender": "Male",
    "ip_address": "104.62.125.170"
  },
  {
    "id": "",
    "first_name": "Gavrielle",
    "last_name": "Danihel",
    "email": "gdanihel3@yandex.ru",
    "gender": "Female",
    "ip_address": "98.98.209.17"
  }
];

let getIndex = array.findIndex(function(item) {
  return item.id === '';

})
let newArray = [];
if (getIndex !== -1) {
  newArray = array.map(function(item) {
    return Object.assign({}, {
      "first_name": item['first_name'],
      "last_name": item['last_name'],
      "email": item['email'],
      "gender": item['gender'],
      "ip_address": item['ip_address'],
      "item.gender": item['item.gender']
    })
  })
}

console.log(newArray)

Alternatively you can use array some & reduce

let array = [{
    "id": "",
    "first_name": "Kary",
    "last_name": "Thorndale",
    "email": "kthorndale1@nifty.com",
    "gender": "Female",
    "ip_address": "172.152.36.109"
  },
  {
    "id": "",
    "first_name": "Westley",
    "last_name": "Emmott",
    "email": "wemmott2@cisco.com",
    "gender": "Male",
    "ip_address": "104.62.125.170"
  },
  {
    "id": "",
    "first_name": "Gavrielle",
    "last_name": "Danihel",
    "email": "gdanihel3@yandex.ru",
    "gender": "Female",
    "ip_address": "98.98.209.17"
  }
];

let __e = array.some((item) => {
  return item.id === '';
})
if (__e) {
  let z = array.reduce(function(acc, curr) {
    let k = Object.assign({}, curr);
    delete k['id'];
    acc.push(k);
    return acc

  }, [])
  console.log(z)
}

Upvotes: 0

Related Questions