2015-09-09 2 views
0

Используя следующий код, я должен проверить, есть ли в массивах (ai, jq и rz) пользователи с тем же «интересом», и если да, удалите это пользователя из всех массивов. Но кажется, что метод .splice() не работает, когда я регистрирую массивы, и они все еще содержат этого пользователя. Есть идеи?NodeJS arr.splice() не удаляется из массива

Код:

function joinQueue(sid, interests, fn) { 
 
\t var exists = false; 
 
\t 
 
\t interests.forEach(function(interest) { 
 
\t \t interest = interest.toLowerCase(); 
 
\t \t getTable(interest.charAt(0), function(table) { 
 
\t \t \t table.forEach(function(data) { 
 
\t \t \t \t if(data.interest == interest && !exists) { 
 
\t \t \t \t \t var aa = 0; 
 
\t \t \t \t \t ai.forEach(function(a) { 
 
\t \t \t \t \t \t if(a.sid == data.sid) { ai.splice(aa, 1); console.log(ai);} 
 
\t \t \t \t \t \t aa++; 
 
\t \t \t \t \t }); 
 
\t \t \t \t \t var jj = 0; 
 
\t \t \t \t \t jq.forEach(function(j) { 
 
\t \t \t \t \t \t if(j.sid == data.sid) { jq.splice(jj, 1); console.log(jq); } 
 
\t \t \t \t \t \t jj++; 
 
\t \t \t \t \t }); 
 
\t \t \t \t \t var rr = 0; 
 
\t \t \t \t \t rz.forEach(function(r) { 
 
\t \t \t \t \t \t if(r.sid == data.sid) { rz.splice(rr, 1); console.log(rz); } 
 
\t \t \t \t \t \t rr++; 
 
\t \t \t \t \t }); 
 
\t \t \t \t \t fn(data); 
 
\t \t \t \t \t exists = true; 
 
\t \t \t \t } 
 
\t \t \t }); \t 
 
\t \t }); 
 
\t }); 
 
\t if(!exists) { 
 
\t \t interests.forEach(function(interest) { 
 
\t \t \t interest = interest.toLowerCase(); 
 
\t \t \t getTable(interest.charAt(0), function(table) { 
 
\t \t \t \t table.push({'sid': sid, 'interest': interest}); 
 
\t \t \t }); 
 
\t \t }); 
 
\t \t fn(); 
 
\t } 
 
}

+0

Можете ли вы предоставить данные, переданные в joinQueue? sid, интересы, fn. Первое, что нужно проверить, - это когда-либо исполняемый код после 'a.sid === data.sid'. – widged

+2

'jq.forEach (function (j, i) {/ * делать то, что добавляет или удаляет элементы в массиве * /}', как правило, не очень хорошая идея. Попробуйте использовать [] .concat (jq) .forEach (d , i) или jq.slice (0). Таким образом, вы будете перебирать клон массива. – widged

+0

Что вы ожидаете, когда находитесь в середине нескольких итераций 'jq.forEach()' и вы вызываете 'jq.splice()' внутри обратного вызова? – jfriend00

ответ

0

[Непроверенные]. Трудно установить, имеет ли значение какие-либо различия без доступа к тестируемому коду (отсутствуют входные данные и некоторые другие переменные).

Лучше всего не добавлять и не удалять элементы в массив, когда вы зацикливаете на нем. Лучше всего перебирать клон массива, а не сам массив. Попробуйте использовать код ниже, чтобы узнать, не имеет значения.

function joinQueue(sid, interests, fn) { 
 
    var exists = false; 
 
\t 
 
    interests.forEach(function(interest) { 
 
     interest = interest.toLowerCase(); 
 
     getTable(interest.charAt(0), function(table) { 
 
      table.forEach(function(data) { 
 
       if(data.interest == interest && !exists) { 
 
        var sid = data.sid; 
 
        var sliceItOff = function(arr) { 
 
         arr.slice(0).forEach(function(d, i) { 
 
          // [warning]. if more than one item meets the condition (d.sid == sid), 
 
          // then you are likely to remove an item at the wrong index. 
 
          // A better approach is to build a new array rather than modify the old one 
 
          if(d.sid == sid) { arr.splice(i, 1); console.log(arr); } 
 
         }); 
 
        }; 
 
        sliceItOff(ai); 
 
        sliceItOff(jq); 
 
        sliceItOff(rz); 
 
        fn(data); 
 
        exists = true; 
 
\t \t \t \t } 
 
\t \t \t }); \t 
 
\t \t }); 
 
\t }); 
 
\t if(!exists) { 
 
\t \t interests.forEach(function(interest) { 
 
\t \t \t interest = interest.toLowerCase(); 
 
\t \t \t getTable(interest.charAt(0), function(table) { 
 
\t \t \t \t table.push({'sid': sid, 'interest': interest}); 
 
\t \t \t }); 
 
\t \t }); 
 
\t \t fn(); 
 
\t } 
 
}

+0

Это работает как шарм. –

+0

У этого нет проблемы, поскольку, как только вы удаляете элемент из исходного массива, индекс в клонированном массиве не совпадает с индексом. Итак, если вы уйдете, чтобы удалить второй элемент, вы удалите неправильный элемент. Он будет работать в первый раз, но не второй. Если в каждом массиве есть только один аргумент 'id', это может сработать, но я думаю, что это плохой шаблон, потому что он может легко сломаться. – jfriend00

+0

Действительно, если более чем один элемент может удовлетворить (d.sid == sid) – widged

1

Вот немного безопаснее вариант, который использует обратную for цикла обхода, чтобы избежать проблем, когда текущий элемент будет удален.

function joinQueue(sid, interests, fn) { 
    var exists = false; 

    interests.forEach(function(interest) { 
     interest = interest.toLowerCase(); 
     getTable(interest.charAt(0), function(table) { 
      table.forEach(function(data) { 
       if(data.interest == interest && !exists) { 
        var sid = data.sid; 
        var sliceItOff = function(arr) { 
         for (var i = arr.length - 1; i >= 0; i--) { 
          if(arr[i].sid == sid) { 
           arr.splice(i, 1); 
          } 
         } 
        }; 
        sliceItOff(ai); 
        sliceItOff(jq); 
        sliceItOff(rz); 
        fn(data); 
        exists = true; 
       } 
      }); 
     }); 
    }); 
    if(!exists) { 
     interests.forEach(function(interest) { 
      interest = interest.toLowerCase(); 
      getTable(interest.charAt(0), function(table) { 
       table.push({'sid': sid, 'interest': interest}); 
      }); 
     }); 
     fn(); 
    } 
} 
+0

Обратный цикл - это гораздо лучший подход, да :-) – widged

Смежные вопросы