Страницы

Поиск по вопросам

четверг, 9 января 2020 г.

Как найти значение которое повторяется чаще всего?

#javascript


Допустим есть такой JSON:

[{"title":"a","cost":"56"},{"title":"b","cost":"34"},{"title":"a","cost":"233"},{"title":"c","cost":"3434"},{"title":"a","cost":"434"}]


Как найти title, который повторяется чаще всего ?
Вот мой вариант, но хотелось бы увидеть более правильное решение



let arr = JSON.parse('[{"title":"a","cost":"56"},{"title":"b","cost":"34"},{"title":"a","cost":"233"},{"title":"c","cost":"3434"},{"title":"a","cost":"434"}]');
let names = [];
for (let i = 0; i < arr.length; i++) {
  names.push(arr[i].title);
}
let counts = {};
let res = 0;
names.forEach(function(x) {
  counts[x] = (counts[x] || 0) + 1;
  if (counts[x] > res) {
    res += counts[x];
  }
});
let max = 0;
let maxName = '';
for (let key in counts) {
  if (max < counts[key]) {
    max = counts[key];
    maxName = key;
  }
}
console.log(maxName); // a



    


Ответы

Ответ 1



Нет смысла делать массив из заголовков - достаточно уже имеющегося. Для словаря вместо пустого объекта лучше использовать Object.create(null), чтобы не было проблем с методами в прототипе объекта. Ещё, если результат не превосходит 231, можно использовать ~~ для приведения к инту - в большинстве случаев помогает от той же проблемы при использовании {} (от всего кроме __proto__). Самых частых может быть несколько. Здесь баг: res += counts[x]; - должно быть просто =, а не +=. Хотя это значение дальше вообще почему-то не используется - непонятно, зачем тогда оно считалось. max < counts[key] - здесь могло бы быть counts[key] === res, если бы в прошлом пункте было написано верно. Я бы сделал так если нужен массив: var arr = JSON.parse('[{"title":"a","cost":"56"},{"title":"b","cost":"34"},{"title":"a","cost":"233"},{"title":"c","cost":"3434"},{"title":"a","cost":"434"}]'); var count = Object.create(null), max = 0, cur; for (var x of arr) { if ((cur = count[x.title] = ~~count[x.title] + 1) > max) { max = cur; } } var res = Object.keys(count).filter(x => count[x] === max); console.log(res); и так, если нужен любой максимум: var arr = JSON.parse('[{"title":"a","cost":"56"},{"title":"b","cost":"34"},{"title":"a","cost":"233"},{"title":"c","cost":"3434"},{"title":"a","cost":"434"}]'); var count = Object.create(null), max = 0, cur, res; for (var x of arr) { if ((cur = count[x.title] = ~~count[x.title] + 1) > max) { max = cur; res = x.title; } } console.log(res);

Ответ 2



данный пример имеет ряд технических недоработок, которые решаются незначительными правками: ©Самых частых может быть несколько вызов obj.increment('increment') obj.increment('max') obj.increment('min') всё поломает спасибо @Qwertiy за замечание предлагаю его рассматривать в ракурсе стилистического оформления (повторяемый код должен быть в функции) void function () { let obj = { increment(_key) { if (!this[_key]) this[_key] = 0 this[_key]++ }, get min() { return; }, get max() { let key = null let count = 0 Object.keys(this).forEach(_key => { if (count < this[_key]) { count = this[_key] key = _key } }) return { key, count }; }, } Object.keys(obj).forEach(_key => { Object.defineProperty(obj, _key, { enumerable: false }) }) obj.increment('a') obj.increment('a') obj.increment('c') obj.increment('c') obj.increment('c') obj.increment('b') let { key, count } = obj.max var co = co || document.getElementById('co') console.log(`ключ:"${key}" количество повторений:"${count}"`) co.innerHTML = `ключ:"${key}" количество повторений:"${count}"` }()


Ответ 3



Как вариант, но ваша реализация читается лучше ... const json = JSON.parse('[{"title":"a","cost":"56"},{"title":"b","cost":"34"},{"title":"a","cost":"233"},{"title":"c","cost":"3434"},{"title":"a","cost":"434"}]'); const titleCounts = json.reduce(( memo, item ) => ({ ...memo, [item.title]: ( memo[item.title] || 0 ) + 1 }), {}); // Считаем сколько раз каждый из `title` встречается const mostFrequent = Object.keys(titleCounts).reduce(( prev, cur ) => titleCounts[prev] > titleCounts[cur] ? prev : cur); // Ищем ключ с наибольшим значением console.log(titleCounts); console.log(mostFrequent);

Комментариев нет:

Отправить комментарий