Remove an element from an array by field names

Viewed 395

I have the next array:

0: {id: "10", tipo: "work"}
1: {id: "11", tipo: "work"}
2: {id: "24", tipo: "school"}
3: {id: "9", tipo: "work"}
4: {id: "25", tipo: "school"}

What I want to do is to remove an element from the array where two values match, for example, if id = 24 and tipo = school, the array at the position 2, must be removed, I have this function to find the array key by the values:

function eliminarElementoArray(array,val1,val2){   
     for (var i=0; i<array.length; i++){
       if (array[i].id == val1 && array[i].tipo == val2)                    
          return i;
       else
          return false;
     }
 } 

The function does not work correctly, in some cases it returns false, others, it returns an incorrect value.

Finally here is where the array values are removed, but it does not work because the previous function does not return the correct values:

selected.splice( eliminarElementoArray(selected, id, tipo), 1);

If someone can help me, I would be grateful.

11 Answers

Problem :

The return false; statement inside for loop: The function will always check the first element of the array then if it does not match it will move to the else clause and return false without looping through the rest of the elements.

Solution :

You should move the return statement out of the loop so if no element of the array matches the passed arguments the function will return false.

NOTE: As @Taplar's comment says, It will be better to return a Truthy (no falsy) value like -1 for example since the splice() method will consider false as zero 0 and remove the first item.

function eliminarElementoArray(array, val1, val2) {
  for (var i = 0; i < array.length; i++) {
    if (array[i].id == val1 && array[i].tipo == val2)
      return i;
  }

  return -1;
}

var my_array = [{id: "10",tipo: "work"}, {id: "11",tipo: "work"}, {id: "24",tipo: "school"}, {id: "9",tipo: "work"}, {id: "25",tipo: "school"}];

console.log(eliminarElementoArray(my_array, "10", "work"));
console.log(eliminarElementoArray(my_array, "11", "fail test"));
console.log(eliminarElementoArray(my_array, "25", "school"));

You can simply use the Array.filter function.

Your code becomes:

const array = [{id: 23, tipo: 'foo'}, {id: 25, tipo: 'school'}, {id: 24, tipo: 'school'}]

const filteredArray = array.filter(element => element.id !== 24 || element.tipo !== 'school')

console.log(filteredArray)

If you use return false inside else, the function will return immediately after the first element.

function eliminarElementoArray(array,val1,val2){   
     for (i in array){
       if (array[i].id == val1 && array[i].tipo == val2)                    
          return i;
     }
     return false;
 } 

Use Array.filter to your advantage.

const deleteElement = (idValue, tipoValue) => {
  return yourArrayName.filter(el => el.id !== idValue && el.tipe !== tipoValue)
}

Then pass the values to the deleteElement function, like so :

newArray = deleteElement('24','work')

data = [
 {id: "10", tipo: "work"},
 {id: "11", tipo: "work"},
 {id: "24", tipo: "school"},
 {id: "9", tipo: "work"},
 {id: "25", tipo: "school"}
]

function removeByIdAndTipo(idValue, tipoValue){
  return data.filter(({ id, tipo })=> { 
   return !(id === idValue && tipo === tipoValue)
  })
}

console.log("filteredData", removeByIdAndTipo("24", "school"))

Shortcut method is

var data=[
   {id: "10", tipo: "work"},
   {id: "11", tipo: "work"},
   {id: "24", tipo: "school"},
   {id: "9", tipo: "work"},
   {id: "25", tipo: "school"}
]

var values=$.grep(data,p=>{
    return !(p.id === "24" && p.tipo === "school")
})

console.log(values)

As other answers already pointed out, there are some logic error (like the function will return directly after first mismatch).

But for your use case, you don't need to loop first to find out that index which match both value, finally use Array.splice remove it.

One solution is Just loop the array, then push mismatch elements to one new array, finally return that new array.

let test = [{
    id: "10",
    tipo: "work"
  },
  {
    id: "11",
    tipo: "work"
  },
  {
    id: "24",
    tipo: "school"
  },
  {
    id: "9",
    tipo: "work"
  },
  {
    id: "25",
    tipo: "school"
  }
]

function eliminarElementoArray(array, val1, val2) {
  let unmatch = []
  for (var i = 0; i < array.length; i++) {
    if (!(array[i].id == val1 && array[i].tipo == val2))
      unmatch.push(array[i])
  }
  return unmatch
}
console.log(eliminarElementoArray(test, 24, 'school'))

The lodash way.

   let arr = [
            { id: "10", tipo: "work" },
            { id: "11", tipo: "work" },
            { id: "24", tipo: "school" },
            { id: "9", tipo: "work" },
            { id: "25", tipo: "school" }
        ];
    function test(array, val1, val2){
            _.remove(array, item =>{
                return item.id == val1 && item.tipo == val2;
            })
        }
    test(arr, '9', 'work');
    console.log(arr);
var arr = [
    {
        id : "1",
        typo: "aba"
    },
    {
        id : "2",
        typo: "school"
    },
    {
        id : "3",
        typo: "alibaba"
    }
];

function removeItemByTypo(arr,id,typo){
    arr.forEach(function(elem,index) {
      if(elem.id == id && elem.typo == typo){
        arr.splice(index,1);
      }
    });
}

removeItemByTypo(arr,"2","school");
console.log(arr);

You can use forEach in array use 2 args is elem and index, elem to find object by id and typo and index to splice it. Hope my answer is clear!

   var array = [];
   array[1] = {id: "10", tipo: "work"};
   array[2] = {id: "11", tipo: "work"};
   array[3] = {id: "24", tipo: "school"};
   array[4] = {id: "9", tipo: "work"};
   array[5] = {id: "25", tipo: "school"};

   function eliminarElementoArray(array,val1,val2){
       for(var i = 1; i < array.length; i++) {
           if(array[i].id == val1 && array[i].tipo == val2) {
              array.splice(i, 1);
              break;
           }
       }
   }
   array.splice(eliminarElementoArray(array,11,"work"), 1);
   console.log(array);
  1. First you should compare the string (tipo) with === and not with ==.

  2. You must delete the else because with this else you're only comparing the first element; your function should be like this:

    function eliminarElementoArray(array,val1,val2){   
      for (var i=0; i<array.length; i++){
        if (array[i].id == val1 && array[i].tipo === val2)                  
            return i;
      }
    }
    

I hope this help you :)

Related