Reputation: 14216
I am looking to prepare an object for send. It initially looks like so :
var myObj = {"state":{"Saved":true,"Committed":false,"Published":false},"discipline":{"Marketing":true}};
And needs to be change via looking at the inner objects and turning it into an array of keys of the objects who's values are true. So in this example it would change into this :
{"state":["Saved"],"discipline":["Marketing"]};
(committed and published were removed because they were set to false. )
Here is what I've tried so far:
function mutate() {
//map obj
return _.map(myObj, function(object){
//pluck keys that have = true
return _.keys(_.pick(object[0], Boolean));
});
}
Struggling with this a bit, and how to traverse and build this correctly. I am using underscore - but plain javascript is fine if it makes more sense. Thanks!
Upvotes: 2
Views: 83
Reputation: 27976
You were nearly there with your answer. Use _.mapObject to retain the keys instead of map.
var result = _.mapObject(myObj, function(value){
return _.keys(_.pick(value, Boolean));
});
Upvotes: 1
Reputation: 48267
You can solve this in vanilla JS using map
, reduce
, and Object.keys
:
var myObj = {
"state": {
"Saved": true,
"Committed": false,
"Published": false
},
"discipline": {
"Marketing": true
}
};
var output = Object.keys(myObj).reduce(function(p, collection) {
var values = myObj[collection];
p[collection] = Object.keys(values).filter(function(key) {
return values[key] === true;
});
return p;
}, {});
document.getElementById('results').textContent = JSON.stringify(output);
<pre id="results"></pre>
This works by:
true
values on that key.The algorithm is fairly simple and should work with almost any object you throw at it. You can change the filter easily and there may be a few optimizations you could try out.
The equivalent with underscore would be:
var myObj = {
"state": {
"Committed": false,
"Saved": true,
"Published": false
},
"discipline": {
"Marketing": true
}
};
var output = _.reduce(myObj, function(p, values, collection) {
p[collection] = _.chain(values).map(function(value, key) {
console.log('filter', arguments);
if (value === true) {
return key;
}
}).filter(function(it) {
return !!it;
}).value();
return p;
}, {});
document.getElementById('results').textContent = JSON.stringify(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<pre id="results"></pre>
Upvotes: 2