I have this array of objects:
[{
"_id": "plastic",
"countries": ['Egypt','','Iran'],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
},
{
"_id": "peak oil",
"countries": ['USA','Russia',''],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
}]
I want to remove empty strings in the countries array. Now here's the catch, I want to remove the same index in likelihood,relevance and intensity as well.
I tried this:
// replacement for splice, array.remove(index)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) 1 || this.length);
this.length = from < 0 ? this.length from : from;
return this.push.apply(this, rest);
};
data.forEach(obj => {
obj.countries.forEach((country,index) => {
if (country === "") {
obj.countries.remove(index)
obj.likelihood.remove(index)
obj.relevance.remove(index)
obj.intensity.remove(index)
}
})
})
Example output on the above data:
[{
"_id": "plastic",
"countries": ['Egypt','Iran'],
"likelihood": [1,3],
"relevance": [1,3],
"intensity": [1,3]
},
{
"_id": "peak oil",
"countries": ['USA','Russia'],
"likelihood": [1,2],
"relevance": [1,2],
"intensity": [1,2]
}]
As you can see the index which was empty in the countries array was removed along with likelihood,relevance,intensity.
How can I achieve this ?
UPDATE
I am in a Node.js environment and trying to run this code:
router.get('/topics/:type', async (req, res,next) => {
// return all the countries,likelihoods,relevances,intensities associated with a single topic
try{
if(req.params.type == "default") {
const data = await Data.aggregate([
{ $match: {} },
{ $group: { _id: "$topic",countries: { $push: "$country" },likelihood: { $push: "$likelihood" },relevance: { $push: "$relevance" },intensity: { $push: "$intensity" } } },
{ $sort: { _id: -1 } }
])
//remove empty strings countries before sending em.
//since we are deleting the values on x axis we need to do the same for y, in order to present a correct graph.
// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) 1 || this.length);
this.length = from < 0 ? this.length from : from;
return this.push.apply(this, rest);
};
let arr = ['','a','','d']
arr.remove(0)
console.log(arr)
data.forEach(obj => {
obj.countries.forEach((country,index) => {
if (country === "") {
obj.countries.remove(index)
obj.likelihood.remove(index)
obj.relevance.remove(index)
obj.intensity.remove(index)
}
})
})
return res.json(data)
} else if (req.params.type == "grid"){
//grid view
const data = await Data.aggregate([
{ $match: {} },
{ $group: { _id: "$topic",countries: { $push: "$country" } } }
])
return res.json(data)
}
} catch (err) {
console.log(err.message)
next(err)
}
});
And this doesn't work at all. What am I doing wrong ?
CodePudding user response:
to remove, you can use splice
const datas=[{
"_id": "plastic",
"countries": ['Egypt','','Iran'],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
},
{
"_id": "peak oil",
"countries": ['USA','Russia',''],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
}];
for (const i in datas){
const rmIdx=datas[i]["countries"].findIndex(val=>val==="");
for (const key of ["countries","likelihood", "relevance","intensity"]){
datas[i][key].splice(rmIdx,1)
}
}
console.log(datas)
CodePudding user response:
Your code works. Can't say it's the cleanest approach, but it correctly removes the values.
Array.prototype.remove = function(from, to) {
var rest = this.slice((to || from) 1 || this.length);
this.length = from < 0 ? this.length from : from;
return this.push.apply(this, rest);
};
const data = [{
"_id": "plastic",
"countries": ['Egypt','','Iran'],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
},
{
"_id": "peak oil",
"countries": ['USA','Russia',''],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
}]
data.forEach(obj => {
obj.countries.forEach((country, index) => {
if (country === "") {
obj.countries.remove(index)
obj.likelihood.remove(index)
obj.relevance.remove(index)
obj.intensity.remove(index)
}
})
})
console.log(data);
However, in your code you are directly editing Array.prototype
. This is a bad practice and can cause issues in the future. Instead, you can directly use Array.splice
to remove the items
const data = [{
"_id": "plastic",
"countries": ['Egypt', '', 'Iran'],
"likelihood": [1, 2, 3],
"relevance": [1, 2, 3],
"intensity": [1, 2, 3]
},
{
"_id": "peak oil",
"countries": ['USA', 'Russia', ''],
"likelihood": [1, 2, 3],
"relevance": [1, 2, 3],
"intensity": [1, 2, 3]
}
]
const cleaned = data.map(thing => {
if (thing.countries.includes('')) {
const index = thing.countries.indexOf('');
thing.countries.splice(index, 1);
thing.likelihood.splice(index, 1);
thing.relevance.splice(index, 1);
thing.intensity.splice(index, 1);
}
return thing;
})
console.log(cleaned);
CodePudding user response:
Replace
data.forEach(obj => {
obj.countries.forEach((country,index) => {
if (country === "") {
obj.countries.remove(index)
obj.likelihood.remove(index)
obj.relevance.remove(index)
obj.intensity.remove(index)
}
})
})
with
data.forEach(obj => {
obj.countries.forEach((country,index) => {
if (country === "") {
obj.countries.remove(index)
obj.likelihood.splice(index) // Using splice is enough.
obj.relevance.splice(index)
obj.intensity.splice(index)
}
})
})
CodePudding user response:
you can use it like this :
let list = ['USA','Russia',''].filter(String)
console.log(list)
it's remove empty values.
for more information you can check it out here
CodePudding user response:
Filters all Falsy values .... :)
const data = [{
"_id": "plastic",
"countries": ['Egypt','','Iran'],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
},
{
"_id": "peak oil",
"countries": ['USA','Russia',''],
"likelihood": [1,2,3],
"relevance": [1,2,3],
"intensity": [1,2,3]
}]
const res = data.map(d => ({ ...d , countries : d.countries.filter(Boolean)}));
console.log(res)