Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 22.11.2017, 17:14
Аспирант
Отправить личное сообщение для ami_moor Посмотреть профиль Найти все сообщения от ami_moor
 
Регистрация: 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 (т.е предыдущее значение)
Ответить с цитированием
  #2 (permalink)  
Старый 23.11.2017, 09:16
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,482

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);
	};
};
Ответить с цитированием
  #3 (permalink)  
Старый 23.11.2017, 09:48
Интересующийся
Отправить личное сообщение для jerseybb Посмотреть профиль Найти все сообщения от jerseybb
 
Регистрация: 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 в 10:12.
Ответить с цитированием
  #4 (permalink)  
Старый 23.11.2017, 10:49
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 30,779

Сообщение от ami_moor
должна вывести a=1,b=2,c=3
a=1,b=1,c=3
Ответить с цитированием
  #5 (permalink)  
Старый 23.11.2017, 10:51
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 30,779

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
Ответить с цитированием
  #6 (permalink)  
Старый 23.11.2017, 11:20
Интересующийся
Отправить личное сообщение для jerseybb Посмотреть профиль Найти все сообщения от jerseybb
 
Регистрация: 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'.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ValueOf. Все точки над И. Vyus Общие вопросы Javascript 4 16.06.2014 21:29
Функция которая отменяет все обработчики и устанавливает свой itoldya jQuery 7 01.11.2012 20:09
Название ячейки таблицы Questioner Общие вопросы Javascript 6 16.02.2011 08:58
Выполняется функция, а все что написано после нее игнорируется, libinstyle Элементы интерфейса 4 24.03.2010 15:44
глюк форума Gvozd Сайт Javascript.ru 11 18.03.2009 13:37