Как написать функцию на js, которая проверяет, был ли уже когда то введен параметр с определенным значением

function make(n) {
    var currentCount = [];
    return function (n) {
        for (var i = 0; i < currentCount.length; i++) {
            if (currentCount[i] === n) {
                console.log('уже была')
            } else {
                console.log('не было')
            }
        }
        currentCount.push(n)
    };
}

var counter = make(); // (*)

counter(2)
counter(1)
counter(2)
counter(2)
counter(2)
counter(2)

Вроде написал, но как то криво работает(((

Функция не должна использовать внешние переменные.

Например f(2) //false, f(1) //false, f(2) //true, f(2) //true, f(12) //false, f(1) //true,


Ответы (1 шт):

Автор решения: EzioMercer

Я не думаю что это возможно в общем случае, потому что нужен алгоритм глубокого сравнения объектов (да их существует куча, но у каждого свои недостатки). Но можно сделать например если речь идёт про примитивные данные и/или передаваемые объекты нужно сравнивать по ссылке, тогда можно:

  1. Вне функции объявить набор new Set()
  2. Каждый раз смотреть есть ли в наборе переданный параметр или нет
  3. Если нет, то добавляем в набор значение параметра и возвращаем false
  4. Иначе возвращаем true

Код:

const memory = new Set();

const f = (param) => {
  if (memory.has(param)) return true;
  
  memory.add(param);
  
  return false;
};

const y = {z: 1};

console.log(1, f(1));
console.log(2, f(2));
console.log(3, f(1));
console.log(4, f(2));
console.log(5, f({x: 1}));
console.log(6, f({x: 1}));
console.log(7, f(y));
console.log(8, f(y));

Ну выводы 1-4 думаю не стоит объяснять. Выводы 5 и 6 - это false, потому что сравниваются объекты по ссылке, а не по значению, а при описании объекта, каждый раз создаётся новый объекта с новой ссылкой. Ну и выводы 7, 8 - false и true потому что мы записали ссылку в переменную и два раза отправили одну и ту же ссылку

Если нужно без внешнего параметра, то можно так (логика точно такая же, просто пользуемся обёрткой):

const wrapper = () => {
  const memory = new Set();
  
  const f = (param) => {
    if (memory.has(param)) return true;
  
    memory.add(param);
  
    return false;
  }
  
  return f;
};

const f = wrapper();

const y = {z: 1};

console.log(1, f(1));
console.log(2, f(2));
console.log(3, f(1));
console.log(4, f(2));
console.log(5, f({x: 1}));
console.log(6, f({x: 1}));
console.log(7, f(y));
console.log(8, f(y));

→ Ссылка