Maddy
Maddy

Reputation: 1668

Ramda: Remove empty object having dynamic keys

I have this object where addon_sizes keys are dynamic i.e "1","2", "3", "4":

const sizes = {
 "addon_sizes": {
        "1": ["a", "b"],
        "2": ["c"],
        "3": null,
        "4": []
    }
}

I need to remove all key/value pairs in this object where the value is null/undefined/empty array.

So the keys "3" and "4" should be removed from the list.

So far what i have tried is:

const newObj = R.reject(R.anyPass([R.isEmpty, R.isNil]))(sizes.addon_sizes);

But this doesn't remove the null or empty values.

Upvotes: 0

Views: 153

Answers (3)

Scott Sauyet
Scott Sauyet

Reputation: 50797

This depends on your definition of remove. If you mean to mutate your original object, then Ramda will offer no help. If you want to create a copy without those properties, your code already seems to work, although it still needs to be applied to your input object. Here we do so with over and lensProp

const cleanAddons = over (
  lensProp ('addon_sizes'), 
  reject (anyPass ([isNil, isEmpty]))
)

const sizes = { addon_sizes: {1: ["a", "b"], 2: ["c"], 3: null, 4: []}}

console .log (cleanAddons (sizes))
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {over, lensProp, reject, anyPass, isNil, isEmpty} = R     </script>

lensProp ('addon_sizes') creates a lens which focuses on the addon_sizes property, and over uses that lens and your reject-based function to create a function that will create a copy of your original object with empty or nil values removed from the addon_sizes.

When using just two function, I find either (f, g) more semantic than anyPass ([f, g]), so I like this version slightly better, but it does the same thing:

const cleanAddons = over (
  lensProp ('addon_sizes'), 
  reject (either (isNil, isEmpty))
)

Upvotes: 0

Ori Drori
Ori Drori

Reputation: 191986

Create a new object by picking all properties that are not empty or nil:

const { pickBy, complement, anyPass, isEmpty, isNil } = R

const fn = pickBy(complement(anyPass([isEmpty, isNil])))

const sizes = {"addon_sizes":{"1":["a","b"],"2":["c"],"3":null,"4":[]}}

const result = fn(sizes.addon_sizes)

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js" integrity="sha512-t0vPcE8ynwIFovsylwUuLPIbdhDj6fav2prN9fEu/VYBupsmrmk9x43Hvnt+Mgn2h5YPSJOk7PMo9zIeGedD1A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

Upvotes: 1

Nora S&#246;derlund
Nora S&#246;derlund

Reputation: 1191

Since you've tagged javascript:

You can iterate through the object entries and use the delete keyword to delete the negative or negative length properties.

const sizes = {
    "addon_sizes": {
        "1": ["a", "b"],
        "2": ["c"],
        "3": null,
        "4": []
    }
};

Object.entries(sizes.addon_sizes).forEach(([ key, value ]) => {
  if(!value || !value.length)
    delete sizes.addon_sizes[key];
});

console.log(sizes);

Upvotes: 0

Related Questions