Amir Rahbaran
Amir Rahbaran

Reputation: 2430

array.splice deletes wrong value and keeps wrong value

I want to have an array with guests who do NOT have "decline" as a response. So, Tooth Fairy is deleted (shouldn't, she "accepted" the invitation) from the array and Jack Frost stays (shouldn't, he "declined" the invitation).

function getAttendees(peopleInvited, responses){
    var coming=peopleInvited;
  responses.map(function(cell){
      if (cell.response=='declined') {
        coming.splice(0,1);
         }         
      });
    return coming;  
}

var people = ['Easter Bunny', 'Tooth Fairy', 'Frosty the Snowman', 
              'Jack Frost', 'Cupid', 'Father Time'];
var responses = [ 
     {name: 'Easter Bunny', response: 'declined'}, 
     {name: 'Jack Frost', response: 'declined'}, 
     {name: 'Tooth Fairy', response: 'accepted'} 
   ];

getAttendees(people, responses); 

Upvotes: 0

Views: 125

Answers (3)

Andy
Andy

Reputation: 63587

You could change the responses array to an object using the names of the people as keys instead. I think that's a bit simpler to manage.

function getAttendees(people, responses) {
    for (var i = 0, l = people.length, out = []; i < l; i++) {
        var response = responses[people[i]];
        if (!response || response && response === 'accepted') {
            out.push(people[i]);
        }
    }
    return out;
}

var people = ['Easter Bunny', 'Tooth Fairy', 'Frosty the Snowman',
    'Jack Frost', 'Cupid', 'Father Time'];

var responses = {
    'Easter Bunny': 'declined',
    'Jack Frost': 'declined',
    'Tooth Fairy': 'accepted'
}

DEMO

Upvotes: 2

Valentin S.
Valentin S.

Reputation: 504

First you need to get the index of the person in the coming array and then use splice to remove that person based on it's index.

function getAttendees(peopleInvited, responses){
  var coming=peopleInvited;
  responses.map(function(cell){
    if (cell.response=='declined') {
      var index = coming.indexOf(cell.name);
      coming.splice(index, 1);
    }         
  });
  return coming;  
}

var people = ['Easter Bunny', 'Tooth Fairy', 'Frosty the Snowman', 
     'Jack Frost', 'Cupid', 'Father Time'];
var responses = [ 
  {name: 'Easter Bunny', response: 'declined'}, 
  {name: 'Jack Frost', response: 'declined'}, 
  {name: 'Tooth Fairy', response: 'accepted'} 
];

getAttendees(people, responses); 

Upvotes: 2

Omri Aharon
Omri Aharon

Reputation: 17064

That's because the order they are listed in the different arrays is different.

First you find the "Easter Bunny" on the responses array, and you delete the first occurrence from coming array without checking what it is. In this case, it corresponds.

Then, you find "decline" by "Jack Frost" and you delete the first (new) occurrence from coming, which is now "Tooth Fairy".

Either change the order so both of the arrays will have the same order, or code it differently to not rely on order (which is better in my opinion).

Upvotes: 1

Related Questions