Подсчет вхождений элементов в массиве Решение JavaScript

первоначально опубликовано на hellodevworld.com

Счастливого седьмого дня из 365 дней программирования! 1 неделя вниз 52 идти. Решение JavaScript для функции, которая подсчитывает, сколько раз что-то появляется в массиве. Это может быть плоский массив или массив массивов.

Отказ от ответственности: существует МНОЖЕСТВО способов решить эту проблему. Это ответ, который я увижу или использую на собеседовании по программированию и приму как правильный ответ.

TLDR: решение находится внизу сообщения.

Проблема

Создайте функцию, которая принимает массив и элемент и подсчитывает, сколько раз этот элемент появляется в массиве. Не игнорируйте заглавные буквы, знаки препинания и пробелы.

Примеры:

itemCounter(["hello", [["Hello", "hello"], [["Hello"]], "Hello", "world"]], "hello"); // 2
      itemCounter([["A", "A", "A", "A", "A", "a"],
        ["a", "A", "A", "A", "A", "A"],
        ["A", "a", "A", "A", "A", "A"],
        ["A", "A", "A", "a", "A", "A"]], "a"); // 4
      itemCounter([1, 2, [3], [4, 5], [4, [[6, 7], 4]]], 4); // 3
      itemCounter([1, 2, [3, 11], [4, 5], [4, [[6, 7], 4]]], 10) // 0

Решение

Давайте напишем, что нам нужно сделать

  • возможность 1
  • создайте функцию, которая принимает массив и элемент для поиска в этом массиве
  • создать переменную для счетчика
  • сгладить массив
  • цикл по массиву
  • каждый раз, когда элемент находится в этом массиве, увеличивайте счетчик
  • вернуть счетчик в конце
  • возможность 2
  • создайте функцию, которая принимает массив и элемент для поиска в этом массиве
  • сгладить массив
  • отфильтровать массив по элементу, который был передан в
  • получить длину этого массива

Решение 1

Сначала нам нужно создать функцию, которая принимает массив и элемент

const itemCounter = (array, item) => {
    //create a variable for a counter
    //flatten the array
    //loop through the array
        //every time the item is found in that array increment the counter
    //return the counter at the end
}

Создайте переменную, которая будет содержать счетчик

const itemCounter = (array, item) => {
    let counter = 0
    //flatten the array
    //loop through the array
        //every time the item is found in that array increment the counter 
    //return the counter at the end
}

Нам нужно сгладить массив, и, поскольку мы не знаем, сколько вложенных массивов, мы собираемся передать .flat() Infinity. .flat() сгладит массив столько раз, сколько вы ему передадите. Поскольку мы не знаем, сколько раз это будет, мы передадим Infinity, что сгладит массив, пока он не станет полностью плоским.

const itemCounter = (array, item) => {
    let counter = 0
    array.flat(Infinity)
    //loop through the array
        //every time the item is found in that array increment the counter
    //return the counter at the end
}

Мы хотим перебрать сглаженный массив, поэтому я собираюсь связать .forEach с .flat(). Это очень похоже на цикл for, только с другим синтаксисом. Чтобы узнать больше об этом, посетите эту страницу MDN.

const itemCounter = (array, item) => {
    let counter = 0
    array.flat(Infinity).forEach(x => {
    })
    //every time the item is found in that array increment the counter 
}

Если элемент, на котором мы сейчас находимся в цикле forEach, соответствует переданному элементу, мы хотим увеличить счетчик. Если нет, мы хотим продолжить цикл.

const itemCounter = (array, item) => {
  let counter = 0
  array.flat(Infinity).forEach(x => {
    if(x == item){ counter++ }
  });
  //return counter
}

И последнее, но не менее важное: нам нужно вернуть счетчик.

const itemCounter = (array, item) => {
  let counter = 0
  array.flat(Infinity).forEach(x => {
    if(x == item){ counter++ }
  });
  return counter
}

Решение 2

Сначала нам нужно создать функцию, которая принимает массив и элемент и сглаживает массив. Это будет то же самое, что и предыдущее решение.

const itemCounter = (array, item) => {
  array.flat(Infinity)
  //filter the array by the item that was passed in
  //get the length of that array
}

Для фильтрации массива мы будем использовать .filter(). Если вы не знакомы с ним, вы можете проверить эту страницу MDN, но он создает новый массив элементов, которые соответствуют критериям в функции, которую вы ему передаете.

const itemCounter = (array, item) => {
  array.flat(Infinity).filter(currentItem => currentItem === item)
  //get the length of that array
}

Теперь нам просто нужно получить длину. Я также собираюсь немного почистить его, и мы получим это.

const itemCounter = (array, item) => array.flat(Infinity).filter(currentItem => currentItem == item).length;

Вывод

В этом случае производительность для каждого одинакова. Мне нравится второе решение, потому что в нем значительно меньше кода и его все еще легко читать, но оба решения хороши. Ниже приведены мои результаты jsbench для тех, кому интересно.

Надеюсь, вам было весело с этим! Пожалуйста, оставьте свои решения, которые вы придумали, в разделе комментариев. Если у вас есть какая-либо задача, которую вы хотели бы решить, также оставьте ее в комментариях ниже, вы можете увидеть, как она появится! Если вы хотите получать по электронной почте задание каждый день утром и уведомление о публикации решения, подпишитесьниже!