38

Lets say I have an object

  filter: {
    "ID": false,
    "Name": true,
    "Role": false,
    "Sector": true,
    "Code": false
  }

I want to set all keys to false (to reset them). What's the best way to do this, I'd like to avoid looping with foreach and stuff. Any neat one liner?

chefcurry7
  • 4,813
  • 11
  • 28
  • 33

9 Answers9

71

Well here's a one-liner with vanilla JS:

Object.keys(filter).forEach(v => filter[v] = false)

It does use an implicit loop with the .forEach() method, but you'd have to loop one way or another (unless you reset by replacing the whole object with a hardcoded default object literal).

nnnnnn
  • 147,572
  • 30
  • 200
  • 241
35

Using lodash, mapValues is a graceful, loop-free way:

filter = {
    "ID": false,
    "Name": true,
    "Role": false,
    "Sector": true,
    "Code": false
};

filter = _.mapValues(filter, () => false);

If you want to do this with Underscore.js, there is an equivalent, but with a slightly different name:

filter = _.mapObject(filter, () => false);

In either case, the value of filter will be set to:

{ ID: false, 
  Name: false, 
  Role: false, 
  Sector: false, 
  Code: false }
Jonathan Eunice
  • 21,653
  • 6
  • 75
  • 77
  • thanks for that. one question, if i want to obtain the property that has value "true" (only one at any time), how best to do it? – chefcurry7 Nov 28 '16 at 02:44
  • 1
    The example data belie the assertion that only one property is `true` at a time. But regardless of however many are, `_.keys(filter).filter(k => filter[k])` will give you a quick array of all keys to values that are truthy. You can use exact equivalence to `true` if you want strictly booleans. And you can always index the resulting array to get the first one: `_.keys(filter).filter(k => filter[k])[0]`. That returns `undefined` if there are none. Sorry for the three instances of "filter" in that expression, but your variable name overloads the function name. – Jonathan Eunice Nov 28 '16 at 03:05
  • @chefcurry7 You might also like `_.find(_.keys(filter), k => filter[k])`. It works similarly, but slighly shorter. – Jonathan Eunice Nov 28 '16 at 03:46
  • This is the best solution if you use lodash! – gandharv garg Oct 15 '18 at 15:26
12

If you're not using ES6, here is its ES5 counterpart.

Object.keys(filter).forEach(function(key, value) {
    return filter[key] = false;
})
Ryan
  • 29
  • 1
  • 4
Joshua Russell
  • 670
  • 5
  • 13
9

If you don't want to modify the array, here's an ES6 alternative that returns a new one:

Object.fromEntries(Object.keys(filter).map((key) => [key, false]))

Explanation:

Object.keys returns the object's keys:

Object.keys({ a: 1, b: 2 }) // returns ["a", "b"]

Then we map the result ["a", "b"] to [key, false]:

["a", "b"].map((key) => [key, false]) // returns [['a', false], ['b', false]]

And finally we call Object.fromEntries that maps an array of arrays with the form [key, value] to an Object:

Object.fromEntries([['a', false], ['b', false]]) // returns { a: false, b: false }
Giovanni Benussi
  • 3,102
  • 2
  • 28
  • 30
4

A small line of code compatible with all browsers:

for(var i in your_object) your_object[i] = false;
Pinguto
  • 416
  • 3
  • 17
3

With ES6 features one-liner without mutation:

{
  ...Object.keys(filter).reduce((reduced, key) => ({ ...reduced, [key]: false }), {})
}
RegarBoy
  • 3,228
  • 1
  • 23
  • 44
  • ` ...Object.keys(filter).reduce((reduced, key) => ({ ...reduced, [key]: false }), {})` should suffce. No need to wrap it in an object – Alan David Garcia Aug 22 '19 at 04:44
  • This worked for my use-case, requiring immutability, though the OP did not state that as a requirement. – Jozzhart Feb 11 '20 at 05:54
2

hasOwnProperty must be used

```

for(var i in your_object) {
  if (Object.hasOwnProperty.call(your_object, i)) {
    your_object[i] = false;
  }
}

```

Alex Shwarc
  • 822
  • 10
  • 20
1

In case you are dealing with 'scope' variables, this might be a better solution.

Object.keys(filter).reduce(function(accObj, parseObj) {
                accObj[parseObj] = false;
                return accObj;
              }, {});
0

Here's what i would call a neat one-liner solution:

const filtered = Object.assign(...Object.keys(filter).map(k => ({ [k]: false })));

Demo:

const filter = {
  'ID': false,
  'Name': true,
  'Role': false,
  'Sector': true,
  'Code': false
};

const filtered = Object.assign(...Object.keys(filter).map(k => ({ [k]: false })));

console.log(filtered);

We are basically converting the object into an array using Object.assign() so we can use the map() fucntion on it to set each propety value to false, then we convert the array back to an object using the Object.assign() with the spread operator :)

Exil
  • 311
  • 2
  • 11
  • 26