22.11.2017, 18:14
|
Аспирант
|
|
Регистрация: 27.08.2013
Сообщений: 32
|
|
функция позволяющая фиксировать все аргументы
Задача взята с http://dkab.github.io/jasmine-tests/?spec=6
Суть: Написать функцию partialAny которая позволяет фиксировать зафиксировать любые аргументы, пропущенные аргументы обозначаются с помощью undefined:
Написала cследующее, но не прошла тестировку, выдаёт следующее "может вызываться несколько раз и результаты во второй раз не зависят от первого" направьте меня как переписать правильно..:
function partialAny() {
var func = arguments[0];
var masArg = [];
var masArg2 = [];
var count = 0;
for(let k=1; k<arguments.length; k++) {
masArg[k-1] = arguments[k];
}
return function() {
for(let k=0; k<arguments.length; k++) {
masArg2[k] = arguments[k];
}
for(let z=0; z<masArg.length; z++) {
if(masArg[z] === undefined) {
masArg[z] = masArg2[count];
count++;
}
}
for(let z=count; z<masArg2.length; z++) {
masArg[masArg.length] = masArg2[z];
}
return func.apply(this, masArg);
}
}
function test(a, b, c) { return "a=" + a + ", b=" + b + ", c=" + c}
var test1_3 = partialAny(test, 1, undefined, 3, undefined);
console.log(test1_3(5, 9, 22, "asdasd")); // a=1,b=5,c=3
console.log(test1_3(1, 2, 4, "7")); // должна вывести a=1,b=2,c=3 а выводит a=1,b=5,c=3 (т.е предыдущее значение)
|
|
23.11.2017, 10:16
|
Профессор
|
|
Регистрация: 04.12.2012
Сообщений: 3,799
|
|
ami_moor, не знаю правильно ли я понял суть задачи, но:
function test(a, b, c) { return 'a=' + a + ',b=' + b + ',c=' + c; }
var _test=partialAny(test,1,undefined,3,undefined);
console.log(_test(5, 9, 22, "asdasd"));
console.log(_test(1, 2, 4, "7"));
function partialAny(callable,_args){
if(!arguments.length)
throw new Error('Missing first argument');
var args=[];
for(var i=0;i<arguments.length;i++){
args[i]=arguments[i];
};
callable=args.shift();
if(typeof callable!='function')
throw new Error('First argument must be function');
return function(){
var _args=args.slice(0);
if(!!arguments.length){
var blanks=[];
for(var i=0;i<_args.length;i++){
if(_args[i]===undefined)
blanks.push(i);
};
for(i=0;i<arguments.length;i++){
var key=blanks.shift();
if(key!==undefined)
_args[key]=arguments[i];
else
_args.push(arguments[i]);
};
};
return callable.apply(window,_args);
};
};
|
|
23.11.2017, 10:48
|
Интересующийся
|
|
Регистрация: 17.11.2017
Сообщений: 10
|
|
function partialAny(fn, ...args) {
return (...args2) => {
return fn(...args.map(arg => arg === undefined ? args2.shift() : arg), ...args2)
}
}
Принцип, если непонятен синтаксис:
1. Проходимся по массиву аргументов функции partialAny и возвращаем новый массив (Array.map)
2. Сравниваем каждый элемент с undefined
3. Если true, заменяем первым элементом из массива аргументов возвращаемой функции (с удалением, Array.shift)
4. Вызываем переданную функцию fn с аргументами из получившегося массива (пункт 1) аргументов, добавляем в конец оставшиеся аргументы из массива аргументов возвращаемой функции (... - оператор spread)
Последний раз редактировалось jerseybb, 23.11.2017 в 11:12.
|
|
23.11.2017, 11:49
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,133
|
|
Сообщение от ami_moor
|
должна вывести a=1,b=2,c=3
|
a=1,b= 1,c=3
|
|
23.11.2017, 11:51
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,133
|
|
ami_moor,
function partialAny() {
var c = arguments[0],
d = [].slice.call(arguments, 1),
a;
return function() {
var e = 0;
a = [].slice.call(arguments, 0);
a = d.map(function(b) {
return void 0 === b ? a[e++] : b
});
return c.apply(this, a)
}
};
function test(a, b, c) { return "a=" + a + ", b=" + b + ", c=" + c}
var test1_3 = partialAny(test, 1, undefined, 3, undefined);
console.log(test1_3(5, 9, 22, "asdasd")); // a=1,b=5,c=3
console.log(test1_3(1, 2, 4, "7")); // a=1,b=1,c=3
|
|
23.11.2017, 12:20
|
Интересующийся
|
|
Регистрация: 17.11.2017
Сообщений: 10
|
|
ami_moor, Ваша ключевая ошибка в том, что результат возвращаемой функции зависит от переменных, которые хранятся в замыкании и которые Вы изменяете:
1. В возвращаемой функции Вы вызываете func с массивом аргументов masArg, который изменили до этого. Чего делать нельзя, так как при последующем вызове функции массив masArg сохранится в замыкании. Перед изменением masArg сделайте копию массива и работайте с ней. К примеру:
let args = masArg.slice()
2. Во вторых, у Вас в замыкании хранится count и в возвращаемой функции эта переменная никак не обновляется. Значит при повторном вызове она будет иметь значение на конец предыдущего вызова функции.
Для исправления Вашего кода вынесите объявление masArg2 и count в начало возвращаемой функции. И перед проверкой на undefined сделайте копию masArg и вносите аргументы уже в копию, аргументы из которой потом передадите в func.
Ну и конечно, как уже сказал рони, результат второго вызова должен быть не 'a=1, b= 2, c=3', а 'a=1, b= 1, c=3'.
|
|
|
|