Получить количество объектов массива, принадлежащих частичному идентификатору в JavaScript/Node js

У меня есть массив таких массивов:

var array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
]

Идентификаторы в приведенном выше массиве (2,3 и 4) динамически поступают из ответа сервера. Мне нужно подсчитать количество записей для определенного идентификатора. Я не могу понять, как перебрать этот массив, чтобы получить ожидаемый результат. Ожидаемый результат:

[{"ID" : "4", Count : "1"},{"ID" : "3", Count : "2"},{"ID" : "2",Count : "3"}]

Обратите внимание, что вывод находится в порядке возрастания счетчика.

Это то, что я пробовал:

var temp1 = [];
                var temp2 = [];
                var temp3 = [];
                for(var i = 0; i < array.length; ++i){
                     if (array[i][0] == 2){
                        temp1.push(array[i])
                     }
                     if (array[i][0] == 1){
                        temp2.push(array[i])
                     }
                     if (array[i][0] == 3){
                        temp3.push(array[i])
                     }

                }

 var output = [{
                    ID: "2",
                    Count: temp1.length,
                },
                {
                    ID: "1",
                    Count: temp2.length,
                },
                {
                    ID: "3",
                    Count: temp3.length
                }]

console.info(output)

Я считаю, что то, как я это делаю, не лучший подход, если данные динамические. Как мне сделать это лучше?

Я обновляю вопрос, пожалуйста, проверьте

node_man 30.05.2019 11:50
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
1
486
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Комбинированное использование Array.prototype.reduce(), Object.entries(), Array.prototype.sort() и Array.prototype.map() даст следующее:

const array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
];

const result = Object.entries(array.reduce((a, [id]) => {
  a[id] = (a[id] || 0) + 1;
  return a;
}, {})).map(([ID, Count]) => ({ID, Count}))
       .sort((a, b) => a.Count - b.Count);

console.info(result);

Можете ли вы предложить мне несколько хороших ресурсов для чтения, чтобы я мог самостоятельно решать такие сложные ситуации

node_man 30.05.2019 14:54

не могли бы вы взглянуть на мой вопрос stackoverflow.com/questions/61493692/…

node_man 29.04.2020 06:05

Вы можете использовать карту и фильтр для преобразования массива и подсчета вхождений, затем вы сортируете массив по свойству count:

const array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
];

const result = [];
array.forEach( item => {
  if (result.find( id => item[0] === id["ID"])){
    return;
  }
  result.push({"ID": item[0], Count: array.filter(ids =>  ids[0] === item[0]).length});
})

// And then sort it
result.sort( (a,b) => a.Count - b.Count);

console.info(result);

Вы можете попробовать это.

var array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
];

var y = {};
var z = [];
array.forEach(x=>{      //creating object which will store freq of Id
  if (!y[x[0]]){
    y[x[0]] = 0;
  }
  y[x[0]]++;
});
Object.keys(y).forEach(x=>{   //converting above object to array
  z.push({'ID': x, 'Count':y[x]});
});
console.info(z.sort((a,b) => a.Count - b.Count))//sorting array as per requirement

Попробуйте использовать Array#prototype#reduce

const array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
];

const res = array.reduce((acc, curr) => {
	let foundElement = acc.find(x => x.id === curr[0]);
	
	if (!foundElement) {
		foundElement = {
			id: curr[0],
			count: 1
		};
		
		acc.push(foundElement);
	}
	else {
		foundElement.count += 1;	
	}
	
	return acc;
}, [])
.sort((a, b) => a.count - b.count);

console.info(res);

Если вы хотите придерживаться своего цикла for, простой способ — проверить для каждого элемента, включен ли он уже в вывод, и если да, то увеличить счетчик как таковой:

var array = [
[ '2','Yes'],
[ '2','Yes'],
[ '2','Yes'],
[ '3','Yes'],
[ '3','Yes'],
[ '4','Yes'],
];

var output = [];

for(var i = 0; i < array.length; ++i) {
  if (!output.find(item => item.ID === array[i][0])){
    output.push({'ID': array[i][0], 'Count': 1});
  } else {
    output.find(item => item.ID === array[i][0]).Count += 1;
  }
}
output.sort( (a,b) => a.Count - b.Count)

console.info(output);

Я также думал, что изначально вывод был просто перевернут, но на самом деле он отсортирован по Count, согласно вопросу.

Robby Cornelissen 30.05.2019 12:13

@RobbyCornelissen абсолютно прав, я пропустил это, спасибо;)

Guillaume Bihet 30.05.2019 13:32

Вы также можете получить ожидаемый результат с помощью приведенного ниже фрагмента кода.

var array = [ 
    [ '2','Yes'],
    [ '2','Yes'],
    [ '2','Yes'],
    [ '3','Yes'],
    [ '3','Yes'],
    [ '4','Yes'],
]

var arrMap = {}

array.map(item => {
    if (arrMap[item[0]]){
     arrMap[item[0]]++ 
    }else{
     arrMap[item[0]] = 1
    } 
})

var resultArr = []

for(var keys of Object.keys(arrMap)){
 resultArr.push({"ID":keys,"Count":arrMap[keys]})
}

Другие вопросы по теме