У меня есть массив таких массивов:
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)
Я считаю, что то, как я это делаю, не лучший подход, если данные динамические. Как мне сделать это лучше?
Комбинированное использование 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);
Можете ли вы предложить мне несколько хороших ресурсов для чтения, чтобы я мог самостоятельно решать такие сложные ситуации
не могли бы вы взглянуть на мой вопрос stackoverflow.com/questions/61493692/…
Вы можете использовать карту и фильтр для преобразования массива и подсчета вхождений, затем вы сортируете массив по свойству 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
, согласно вопросу.
@RobbyCornelissen абсолютно прав, я пропустил это, спасибо;)
Вы также можете получить ожидаемый результат с помощью приведенного ниже фрагмента кода.
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]})
}
Я обновляю вопрос, пожалуйста, проверьте