Hi I am trying to delete an element which is inside array of array. my schema is :
var mySchema = Schema({
primaryField:String,
list1: [{
item1: String,
item2:String
}],
list2 : [{
item3:String,
item4 : [String]//item4 is string values available in item1
}]
});
for ex:
{
"primaryField": "abc",
"list1": [{
"item1": "aa",
"item2": "mystring"
},{
"item1": "bb",
"item2": "sampStr"
}],
"list2": [{
"item3": "stringitem",
"item4": ["aa", "bb"]
},{
"item3": "sample",
"item4": ["bb"]
},{
"item3": "samplestring",
"item4": ["aa"]
}]
}
I have to delete the "aa" items from list1 and the occurence of "aa" in list2.item4 and if only "aa" is present in item4 then i have to delete the entire object entry.
my output should be:
{
"primaryField": "abc",
"list1": [{
"item1": "bb",
"item2": "sampStr"
}],
list2:[{
"item3": "stringitem",
"item4": ["bb"]
},{
"item3": "sample",
"item4": ["bb"]
}]
}
could anyone help me to achieve this using node.js and mongoose. Schema cannot be modified.
This produce the expected output. It should be generic enough, and I'm not sure if it will work with your code, but given what's specified in the question, I think it should be fine.
function removeAllItems(obj, value) {
var deleted;
if (!obj) {
return false;
}
if (obj === value) {
deleted = true;
} else if (Array.isArray(obj)) {
for (var i = 0, len = obj.length; i < len; ++i) {
if (removeAllItems(obj[i], value)) {
obj.splice(i--, 1);
if (!obj.length) {
deleted = true;
}
}
}
} else if (typeof obj === 'object') {
for (var keys = Object.keys(obj), key, i = 0, len = keys.length; i < len; ++i) {
if (removeAllItems(obj[keys[i]], value)) {
delete obj[keys[i]];
deleted = true;
}
}
}
return deleted;
}
Tested with :
var test = {
"primaryField": "abc",
"list1": [{
"item1": "aa",
"item2": "mystring"
},{
"item1": "bb",
"item2": "sampStr"
}],
"list2": [{
"item3": "stringitem",
"item4": ["aa", "bb"]
},{
"item3": "sample",
"item4": ["bb"]
},{
"item3": "samplestring",
"item4": ["aa"]
}]
};
var valueToRemove = 'aa';
removeAllItems(test, valueToRemove);
console.log('Removing all', valueToRemove, JSON.stringify(test, null, 2));
Gives the result
Removing all aa {
"primaryField": "abc",
"list1": [
{
"item1": "bb",
"item2": "sampStr"
}
],
"list2": [
{
"item3": "stringitem",
"item4": [
"bb"
]
},
{
"item3": "sample",
"item4": [
"bb"
]
}
]
}
Here is an update that take into account cyclical references, and returns true if any value was removed, or false otherwise.
function removeAllItems(obj, value) {
var stack = [];
var found = false;
function _next(obj) {
var deleted;
if (!obj) {
return false;
} else if (stack.indexOf(obj) >= 0) {
return false; // cyclical reference found
}
stack.push(obj);
if (obj === value) {
found = deleted = true;
} else if (Array.isArray(obj)) {
for (var i = 0, len = obj.length; i < len; ++i) {
if (_next(obj[i])) {
obj.splice(i--, 1);
if (!obj.length) {
deleted = true;
}
}
}
} else if (typeof obj === 'object') {
for (var keys = Object.keys(obj), key, i = 0, len = keys.length; i < len; ++i) {
if (_next(obj[keys[i]])) {
delete obj[keys[i]];
deleted = true;
}
}
}
stack.pop();
return deleted;
}
return _next(obj), found;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With