2016-02-14 4 views
1

Я попытался удалить несколько слов в соответствии с передающей переменной.Удаление конкретных аргументов

Однако, я написал две версии кода, которые имеют незначительные отличия!

И они привели к различным видам продукции, которые я не понимаю, почему!

Так что мне нужно, чтобы вы помогли вам, и большое спасибо за вас, ребята!

Эта функция будет принимать различные числа переменных,

, которые могли бы быть ([обр], 1,2) или ([обр], 1,2,8,9 ...) и т. д.

и удалите переменную в первом массиве в соответствии с пропущенными числами.

Например: разрушитель ([1, 2, 3, 4], 2, 3) -> выход должен быть [1,4]

И вот мой код. (Обратите внимание на небольшую разницу с жирным шрифтом!)

function destroyer(arr) { 
    for (var i = 1; i < arguments.length; i++){ 
     arr = arguments[0].filter(function(value){ 
     if(value == arguments[i]){ 
      return false; 
     }else{ 
      return true; 
     } 
     }); 
    } 
    return arr; 
} 
destroyer([1, 2, 3, 1, 2, 3], 2, 3); 

Выход будет [1,2,3,1,2,3], что означает значение == аргументы [я] не работает. Тем не менее,

function destroyer(arr) { 
    for (var i = 1; i < arguments.length; i++){ 
     filter = arguments[i]; 
     arr = arguments[0].filter(function(value){ 
     if(value == filter){ 
      return false; 
     }else{ 
      return true; 
     } 
     }); 
    } 
    return arr; 
} 
destroyer([1, 2, 3, 1, 2, 3], 2, 3); 

Эта версия работает отлично показывает мне [1,1].

Так что же случилось с первой версией ??? Спасибо!!

+0

Могу ли я предложить более чистую альтернативу код - https://jsfiddle.net/2zm32uom/1/ –

ответ

2

Проблема с первым является то, что arguments относится к функции обратного вызова (.filter() ближайшей области видимости функции, а не область видимости функции родителя), так arguments[i] не то, что вы хотите быть.

Вы можете скопировать эти аргументы в фактический массив, который затем можно было бы ссылаться на обратный вызов .filter().

function destroyer(arr) { 
 
    var args = [].slice.call(arguments, 1); 
 
    for (var i = 0; i < args.length; i++){ 
 
     arr = arr.filter(function(value){ 
 
     if(value == args[i]){ 
 
      return false; 
 
     }else{ 
 
      return true; 
 
     } 
 
     }); 
 
    } 
 
    return arr; 
 
} 
 
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3); 
 

 
// show output 
 
document.write(JSON.stringify(a));


Лично я хотел бы предложить несколько более простой вариант:

function destroyer(arr) { 
 
    var args = [].slice.call(arguments, 1); 
 
    return arr.filter(function(value) { 
 
     return args.indexOf(value) === -1; 
 
    }); 
 
} 
 
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3); 
 

 
// show output 
 
document.write(JSON.stringify(a));


Что можно записать проще в ES6 с использованием спреда оператора:

function destroyer(arr, ...args) { 
 
    return arr.filter(function(value) { 
 
     return args.indexOf(value) === -1; 
 
    }); 
 
} 
 
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3); 
 

 
// show output 
 
document.write(JSON.stringify(a));


Или, если вы предпочитаете еще короче ES6 обозначения и хотите использовать новый Array.prototype.includes():

function destroyer(arr, ...args) { 
 
    return arr.filter(value => !args.includes(value)); 
 
} 
 
var a = destroyer([1, 2, 3, 1, 2, 3], 2, 3); 
 

 
document.write(JSON.stringify(a));

+0

Ха-ха, я просто получаю готов опубликовать вторую версию, которую вы разместили _verbatim_ (ну, я использовал 'Array.from (arguments);', но кроме этого ...). Ура! –

+0

@ RobM. - Я добавил также версию ES6. – jfriend00

+0

, если вы собираетесь ES2015 ... 'return arr.filter (value =>! ~ Args.indexOf (value))' ... или ... 'return arr.filter (value =>! Args.includes (value)) ' –

0

Я хотел бы написать его, как, что в версии ES6:

function destroyer(arr, ...elem) { 
    return arr.reduce((prev, next, index) => elem.includes(arr[index]) ? prev : prev.concat(next) , []) 
} 
+0

Спасибо за помощь! @Avraam Mavrids –

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

  • Нет связанных вопросов^_^