Испытание "Уникальные элементы"

Почему тогда мой не работает

Моя жалка попытка

for (i=0; i<=numbers.length-1; i++) {
var tefal = true;
for (j=0; j<=numbers.length; j++) {
if (numbers[i] === numbers[j] && i!==j) {
tefal = false;
}
}
if (tefal = true) {
uniqueNumbers.push(numbers[i]);
}
}

Code
const tempArr = [];

numbers.forEach(item => {
  if (!uniqueNumbers.includes(item) && !tempArr.includes(item)) {
    uniqueNumbers.push(item);
  } else {
    tempArr.push(item);
    while (uniqueNumbers.includes(item)) {
      const i = uniqueNumbers.indexOf(item);
      
      uniqueNumbers.splice(i, 1);
    }
  }
});

Мой вариант

var numbers = [1, 4, 5, 9, 2, 5, 1];
var uniqueNumbers = [];

for (var i = 0; i < numbers.length; i++) {
if (numbers.indexOf(numbers[i]) == numbers.lastIndexOf(numbers[i])) {
uniqueNumbers.push(numbers[i]);
}
}
console.log(uniqueNumbers);

Объясните, пожалуйста, почему в курсах используется let, а не var?
И есть ли смысл вообще использовать let?

let numbers = [1, 4, 5, 9, 2, 5, 1];
let uniqueNumbers = [];
let copy = 0;

for (let i = 0; i < numbers.length; i++) {
  
  for (let j = 0; j < numbers.length; j++) {
    if (numbers[j] === numbers[i] && j !== i) {
      copy = numbers[i];
    }
  }
  
  if (copy !== numbers[i]) {
    uniqueNumbers.push(numbers[i]);
  }
}

как раз верный вопрос был бы “есть ли смысл вообще использовать var?” т.к. var это легаси вариант уже. Он не применяется уже, разве что в проектах с “бородой”.

Но почему тогда практически все примеры кода на форуме именно с использованием var?
И как я понял между ними есть разница, let более ограниченный вариант, тогда почему лучше использовать его?

потому что авторы курсов мягко говоря подзабили на актуальность. var устарел еще в ES-2015> как раз когда эти курсы появились и только сейчас в 2020 они очухались и стали переписывать примеры, хотя это нужно было сделать еще 5 лет назад.
let не хуже, у него другая область видимости.

Но получается, что var более универсальный вариант, разве нет?

нам не надо универсальный. нам надо избегать ошибок переписывания переменных из неожиданной области видимости

Интересно, моя идея реализации с помощью переключателей true/false

let numbers = [1, 4, 5, 9, 2, 5, 1];
let uniqueNumbers = [];

for (let i = 0; i <= numbers.length - 1; i++) {
 let uniqueDigit = numbers[i];
 let pushUnique = true;

 for (let j = 0; j <= numbers.length - 1; j++) {
   if (uniqueDigit == numbers[j] && j != i) {
   pushUnique = false;
   }
  }

if (pushUnique === true) {
 uniqueNumbers.push(uniqueDigit); 
 }
}

Мой вариант. похоже самый распространенный.

let numbers = [1, 3, 5, 7, 9, 11, 12];

for (let i = 0; i <numbers.length/2;i++) {
let swap = numbers[i];
numbers[i] = numbers[numbers.length-1-i];
numbers[numbers.length-1-i] = swap;
};

let numbers = [1, 4, 5, 9, 2, 5, 1];
let uniqueNumbers = [];
let re = 0;

for(let i=0; i<numbers.length; i++){
re = 0;
for(let j=0; j<numbers.length; j++){
if(numbers[i] === numbers[j]){
re++;
}
}
if(re===1){
uniqueNumbers.push(numbers[i])
}
}

Решил таким способом.
Брал искомый элемент, менял его местами с нулевым индексом, затем, начиная с первого индекса, проверял, есть ли еще индекс с таким значением, если нет (-1), то добавлял элемент на нулевом индексе в новый массив.
К сожалению упустил информацию про lastIndexOf()

Сводка
let numbers = [1, 7, 3, 4, 2, 1, 6, 3];
let uniqueNumbers = [];

for (let i = 0; i <= numbers.length - 1; i++) {
  let swap = numbers[0]
  numbers[0] = numbers[i]
  numbers[i] = swap
  
  if (numbers.indexOf(numbers[0], 1) == -1) {
    uniqueNumbers.push(numbers[0])
  }
  
}
1 лайк

Не понял, как работает это сравнение. Как я понимаю логику - мы берём i-тый индекс и последний индекс и если они равны - то записываем значение в новый массив. Но программа работает наоборот и мне не понятно почему. Можете объяснить?

что значит “работает наоборот”?
вы верно поняли логику.
на каждой итерации вызывается метод indexOf, который возвращает индекс первого вхождения элемента в массиве. если этот индекс совпадает с результатом вызова метода lastIndexOf (который возвращает индекс первого вхождения данного элемента в массиве с обратной стороны), то значит элемент уникальный и мы записываем его значение в результирующий массив, который и должен содержать только уникальные элементы.

Но как?
К примеру такой массив: [1, 2, 3, 1]
Мы сравниваем первый и последний, они равны и записываем их в массив уникальных, но они же не уникальны, а одинаковы.

мы сравниваем не элементы массива, а их индексы. прочитайте про методы массива:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf

Как же круто сделала, молодец! И спасибо, что поделилась.

Вот мой вариант

    let numbers = [1, 4, 5, 9, 2, 5, 1];
    let uniqueNumbers = [];

    for (let i = 0; i <= numbers.length-1; i++) {
      if (numbers.lastIndexOf(numbers[i]) === i && numbers.indexOf(numbers[i]) === i) {  
        uniqueNumbers.push(numbers[i]);
      }
     }
    }

Подскажите, пожалуйста, что значит эта 1? Откуда она и как работает?