Reputation: 16748
I'm trying to get rid of the properties 5MinuteRate
and 15MinuteRate
in the following object.
var object = { requestsPerSecond:
{ mean: 1710.2180279856818,
count: 10511,
'currentRate': 1941.4893498239829,
'1MinuteRate': 168.08263156623656,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095 } };
Lodash's omit()-function doesn't seem to work on nested objects. The following code doesn't work:
console.log(_.omit(object, 'requestsPerSecond.count'));
EDIT:
I tried this but it doesn't work quite right:
var subObject = _.omit(object.requestsPerSecond, '5MinuteRate', '15MinuteRate');
console.log(_.merge(object, subObject));
Upvotes: 16
Views: 37737
Reputation: 1339
If you are like me trying to do this for omitBy which is not supporting nested filtering yet, you can use this following code
const inputObject = {
operation: "category",
params: {
city: undefined,
location: {
latitude: undefined,
value: "not undefined"
},
},
id: "test_id___20200101000000000",
crawler: "crawler_id",
queue: "task_queue",
job: "crawler_id_scheduler_platform",
seedId: "test_id",
};
function removeUndefined(obj) {
return _.omitBy(obj, _.isUndefined);
}
function deepRemoveUndefined(obj) {
if (_.isObject(obj)) {
return removeUndefined(
_.mapValues(obj, (val) => (val && _.isObject(val) ? deepRemoveUndefined(val) : val))
);
}
return obj;
}
const cleanedObject = deepRemoveUndefined(inputObject);
console.log(cleanedObject);
Upvotes: 0
Reputation: 181
I had the same issue but it wanted to omit all the named properties in a nested object.
Here's a generic function that would have worked for you also.
Just use it like this omit(object, ['name_1','name_2, ... ])
// Variation on omit to recurse through objects and arrays
function omit(obj, arr) {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (arr.includes(key)) {
delete obj[key];
} else if (Array.isArray(obj[key])) {
for (let i = 0; i < obj[key].length; i++) {
omit(obj[key][i], arr);
}
} else if (typeof obj[key] === 'object') {
omit(obj[key], arr);
}
}
}
return obj;
}
var object = {
requestsPerSecond: {
mean: 1710.2180279856818,
count: 10511,
'currentRate': 1941.4893498239829,
'1MinuteRate': 168.08263156623656,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095
}
};
object = omit(object, ['5MinuteRate','15MinuteRate']);
console.log(object);
and you should get a result like this
{
"requestsPerSecond":
{
"mean": 1710.2180279856818,
"count": 10511,
"currentRate": 1941.4893498239828,
"1MinuteRate": 168.08263156623656
}
}
I would have liked to have used a later library I'm running test-cases inside Postman, so I'm limited in packages and versions.
Upvotes: 2
Reputation: 7061
If you are open to trying another library, partial.lenses has great support for all kind of operations on collections, including complex modifications like all the children of an object and so on.
So in your case it would be as simple as (L is just a shorthand for the import from partial.lesnes)
const newObject = L.remove(['requestsPerSecond','5MinuteRate'],object)
Now imagine that you have a different structure, where you have a set of nested properties with different names, but all with the same structure, and you want to target all of them. Imagine this example:
obj = {
requestsPerSecond: {
first: {
mean: 1710.2180279856818,
count: 10511,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095
}}
second: {
mean: 1710.2180279856818,
count: 10511,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095
}}
};
In that case, it will be as simple as:
const newObject = L.remove(['requestsPerSecond',L.children,'5MinuteRate'],object)
Where L.children means to target all children of requestPerSecond.
Upvotes: 0
Reputation: 4109
Lodash _.omit works with nested objects. It appears that they improved the function since your question :)
object = _.omit(object, 'requestsPerSecond.5MinuteRate', 'requestsPerSecond.15MinuteRate');
UPDATE
omit will be removed from Lodash 5 onward
Upvotes: 7
Reputation: 1463
In case you need to omit some kind of paths deeply, here is an omitDeep from Deepdash:
obj = _.omitDeep(obj, /\.*5MinuteRate"\]$/);
note that this method will exclude all the matching paths at any depths. It supports a single path or array, represented as a constant value(s) or as a regex(es).
In the case of a string path given as an argument, each path in the object will be checked to end with given criteria. here is a more detailed codepen for your case
(Answer updated to fit most recent Deepdash v3.1.0)
Upvotes: 2
Reputation: 2347
Use unset: https://lodash.com/docs#unset , it gets cleaner:
var obj = {
requestsPerSecond: {
mean: 1710.2180279856818,
count: 10511,
'currentRate': 1941.4893498239829,
'1MinuteRate': 168.08263156623656,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095
}
};
_.forEach(['requestsPerSecond.5MinuteRate', 'requestsPerSecond.15MinuteRate'],
function(omitProperty) {
obj = _.unset(obj, omitProperty);
}
);
// Or avoiding the "extra" loop.
obj = _.unset(obj, 'requestsPerSecond.5MinuteRate');
obj = _.unset(obj, 'requestsPerSecond.15MinuteRate');
Upvotes: 7
Reputation: 9690
You were almost there. Just assign what would be the result of your subObject
to object.requestsPerSecond
.
var object = {
requestsPerSecond: {
mean: 1710.2180279856818,
count: 10511,
'currentRate': 1941.4893498239829,
'1MinuteRate': 168.08263156623656,
'5MinuteRate': 34.74630977619571,
'15MinuteRate': 11.646507524106095
}
};
object.requestsPerSecond = _.omit(object.requestsPerSecond, '5MinuteRate', '15MinuteRate');
console.log(object);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>
Upvotes: 15