Home > Back-end >  Javascript: How to remove empty string values from an array?
Javascript: How to remove empty string values from an array?

Time:02-13

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)

  • Related