Как я могу вернуть только количество совпадающих парных значений в массиве?

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

Я хочу отобразить количество парных значений размеров обуви в массиве. Например, у меня есть этот массив:

[10,10,10,10,20,20,20,30,50]

Я хотел бы отобразить 3, потому что у нас есть 3 пары чисел:

10,10
10,10
20,20

И 3 оставшихся значения, у которых нет совпадающих парных значений (20,30,50).

Как я могу это сделать?

function pairNumber(arr) {
  var sorted_arr = arr.sort();
  var i;
  var results = [];
  for (i = 0; i < sorted_arr.length; i++) {
    if (sorted_arr[i + 1] == sorted_arr[i]) {
      results.push(sorted_arr[i]);
    }

  }
  return results.length;
}
console.log(pairNumber([10, 10, 10, 10, 20, 20, 20, 30, 50]))

Ответ 1

Вот еще один подход с использованием Set:

function pairNumbers(arr) {
  let count = 0;
  const set = new Set();

  for (let i = 0; i < arr.length; i++) {
    if (set.delete(arr[i])) {
      count++;
    } else {
      set.add(arr[i])
    }
  }

  return count;
}
console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50])) // 3

Ответ 2

Я бы уменьшил в объект, подсчитав количество вхождений каждого числа. Затем снова уменьшите Object.values объекта, чтобы подсчитать количество пар, добавив Math.floor(count / 2) к аккумулятору на каждой итерации:

function pairNumber(arr) {
  const itemCounts = arr.reduce((a, item) => {
    a[item] = (a[item] || 0) + 1;
    return a;
  }, {});
  return Object.values(itemCounts)
    .reduce((pairsSoFar, count) => pairsSoFar + Math.floor(count / 2), 0);
}
console.log(pairNumber([10, 10, 10, 10, 20, 20, 20, 30, 50]))

Ответ 3

Если я хорошо понял вопрос, то это можно еще больше упростить, полагаясь сначала на сортировку...

Увеличьте i до следующей позиции после нахождения пары и позвольте циклу for увеличить его еще раз.

 function pairNumber(arr) {
    const sorted_arr = [...arr].sort(); // disallowing array mutation
    let cnt = 0;
    for (let i = 0; i < sorted_arr.length; i++) {
      if (sorted_arr[i + 1] === sorted_arr[i]) {
        cnt++;
        i = i + 1;
      }

    }
    return cnt;
  }
  console.log(pairNumber([10, 10, 10, 10, 10, 20, 20, 20, 20, 30, 30, 50]))
  // 5 --> 2 pairs of 10, 2 pairs of 20, 1 pair of 30
  console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50])) 
  // 3 --> 2 pairs of 10 one pair of 20

Ответ 4

Большое спасибо всем ребятам, которые помогают мне понять, как решить эту проблему. Изучив ответы в посте, я придумаю собственное решение.

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

function pairNumbers(arr) {
  const sorted_arr = arr.sort();
  const results = [];
  for (let i = 0; i < sorted_arr.length; i++) {
    if (sorted_arr[i] == sorted_arr[i + 1]) {
      results.push(sorted_arr[i]);
      i = i + 1; 
    }
  }
  return results.length;
}
console.log(pairNumbers([10, 10, 10, 10, 20, 20, 20, 30, 50])) // 3