@alexei_2002

Как посчитать количество элементов массива, имеющих определённое свойство?

Есть массив объектов:

[
  { special: {} },
  { special: {} },
  { subject: {} },
  { subject: {} },
  { subject: {} },
  { subject: {} },
]

Надо посчитать количество элементов массива с ключом "special".
  • Вопрос задан
  • 662 просмотра
Решения вопроса 2
0xD34F
@0xD34F Куратор тега JavaScript
Конечно, можно прямо посчитать количество интересующих нас элементов:

const countWithKey = (arr, key) => arr.filter(n => key in n).length;

console.log(countWithKey(arr, 'ключ'));

Но можно решить задачу и в более общем виде.

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

const sum = (data, val = n => n) =>
  Array.prototype.reduce.call(
    data,
    (acc, n) => acc + val(n),
    0
  );

console.log(sum(arr, obj => obj.hasOwnProperty('ключ')));

Кстати, что даёт более общий вид.
Считать можно разные суммы. Как, например, обычных массивов из чисел (sum([ 1, 2, 3 ]) // 6), так и более сложные варианты. Например, есть массив, представляющий содержимое корзины с товарами (цена, количество), надо посчитать общую стоимость:

const cart = [
  { price: 100, count: 5 },
  { price:  10, count: 6 },
  { price:   1, count: 7 },
];

const total = sum(cart, item => item.price * item.count); // 567

Или, считаем количество лайков за ответы на этот вопрос (можете открыть консоль и прямо там выполнить этот код):

const likes = sum(document.querySelectorAll('.btn_like .btn__counter'), n => +n.innerText);


Или, можно посчитать, сколько элементов набора данных относится к той или иной группе. Функция подсчёта помимо данных получает в качестве параметра функцию, которая принимает элемент данных, и возвращает группу, к которой он относится:

function Counter(data, key = n => n) {
  const counted = new Map;

  for (const n of data) {
    const k = key(n);
    counted.set(k, (counted.get(k) ?? 0) + 1);
  }

  return k => counted.get(k) ?? 0;
}

const keyExists = Counter(arr, obj => Object.hasOwn(obj, 'ключ'));
console.log(keyExists(true)); // смотрим, у скольких элементов массива ключ есть
console.log(keyExists(false)); // и у скольких нет

Аналогично суммированию, есть разные варианты применения.

const str = 'hello, world!!';

const chars = Counter(str);
console.log(chars('h')); // 1
console.log(chars('!')); // 2
console.log(chars('x')); // 0

const persons = [
  { name: 'Вася', birthday: new Date('1999-05-22') },
  { name: 'Маша', birthday: new Date('2004-03-06') },
  { name: 'Катя', birthday: new Date('1976-05-15') },
  { name: 'Петя', birthday: new Date('1987-04-18') },
  { name: 'Коля', birthday: new Date('2000-01-01') },
  { name: 'Дима', birthday: new Date('2003-05-09') },
  { name: 'Миша', birthday: new Date('1996-02-29') },
  { name: 'Таня', birthday: new Date('1981-03-12') },
  { name: 'Олег', birthday: new Date('1992-08-24') },
];

const birthMonths = Counter(
  persons,
  ({ birthday }) => birthday.toLocaleString('ru-RU', { month: 'long' })
);
console.log(birthMonths('май')); // в мае родилось три человека
console.log(birthMonths('март')); // в марте два
console.log(birthMonths('октябрь')); // а в октябре никто

function* naturalNumbers(n) {
  for (let i = 1; i <= n; i++) {
    yield i;
  }
}

const numLengths = Counter(naturalNumbers(100), num => `${num}`.length);
console.log(numLengths(2)); // среди первых ста натуральных чисел - девяносто двухзначных
console.log(numLengths(3)); // и одно трёхзначное
console.log(numLengths(0)); // число из нуля знаков? - конечно же нет таких

Ответ написан
coderisimo
@coderisimo Куратор тега JavaScript
const totalSpecials = data.filter(i=>i.special).length;
// где data - ваш массив.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы