Как выбрать значение с наименьшим «счетчиком» в объекте Javascript

Используя функцию lodash _.countBy, я создал объект tally, подсчитывающий, сколько раз значение встречается в массиве.

Как лучше всего выбрать наименьшее количество в объекте «значение -> количество»?

 var/input = ["A","A","B","B","C"];
 var/tally = _.countBy(input); // Tally is {"A":2, "B":2, "C":1}

 // [...solution...]

 Console.assert(lowest == "C");

Никакой специальной обработки ничьей не требуется, при условии, что она имеет наименьшее количество очков. Лодаш доступен.

Это можно перефразировать, дайте мне секунду

coiax 13.11.2018 22:41

Я действительно думаю, что вопрос требует некоторой доработки, но я отозвал свой закрытый голос после того, как внимательно прочитал его

Dexygen 13.11.2018 22:41

В вопросе написано lodash, а на бирке написано underscore.js. Что вы на самом деле используете? Я знаю, что они похожи, но не идентичны, поэтому вам следует правильно пометить теги.

Barmar 13.11.2018 22:47

Я думал, что они такие же, а underscore.js - старое название для lodash. Я исправил теги.

coiax 13.11.2018 22:49

Мне нужен элемент, который меньше всего встречается во входном массиве. Я использовал _.countBy, чтобы помочь в этом, но могут быть способы сделать это без использования _.countBy. Они могли бы быть лучше, я не знаю.

coiax 13.11.2018 22:52
Поведение ключевого слова "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
5
424
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

Вы можете уменьшить массив ключей и получить наименьший ключ, проверив значение.

var tally = { A: 2, B: 2, C: 1 },
    lowest = Object.keys(tally).reduce((a, b) => tally[a] < tally[b] ? a : b);

console.info(lowest);

Подход lodash путем объединения свойств и получения минимума с индексом 1 и взятия первого элемента массива.

var input = ["A", "A", "B", "B", "C"],
    lowest = _(input)
        .countBy()                    // { A: 2, B: 2, C: 1 }
        .toPairs()                    // [["A", 2], ["B", 2], ["C", 1]]
        .minBy(1)                     // ["C", 1]
        [0];

console.info(lowest);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

это намного чище

BotNet 13.11.2018 23:03

Этого можно добиться следующим образом:

var tally = {"A":2, "B":2, "C":1};

var tallyItemSmallestKey = Object
.entries(tally)
.sort((entry0, entry1) => entry0[1] - entry1[1] < 0 ? -1 : 1)
.map(entry => entry[0])[0];

console.info( tallyItemSmallestKey );

Это можно было бы сократить до решения, отличного от _, если отсортировать входной массив:

const input = ["A","A","B","B","C"].sort();

let curr = { count: 0 }, result = { count: 0 };
for(const value of input) {
  if (value === curr.value) curr.count++;
  else curr = { value, count: 1 };

  if (curr.count > result.count) result = curr;
}

console.info(result.value);

Вы можете получить подсчеты, а затем проверить минимальную

const input = ["A", "A", "B", "B", "C"]

// get counts
const tally = input.reduce((obj, char) => {
  if (!obj[char])
   obj[char]=1
  else
   obj[char]++
  return obj
}, {})

// get min
let char = Reflect.ownKeys(tally).reduce((keep,current)=>{
  if (!keep) keep = current
  if (tally[current] < tally[keep])
     keep = current
  return keep
}, '')

console.info(char)
console.info(`'${char}' == 'A'`,char == 'A')
console.info(`'${char}' == 'C'`,char == 'C')

С lodash вы можете использовать countBy, entries и minBy примерно так:

const input = ["A", "A", "B", "B", "C"]

const result = _.minBy(_.entries(_.countBy(input)), 1)
console.info(_.head(result))  // or just result[0]
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Или через цепочку lodash:

const input = ["A", "A", "B", "B", "C"]

const result = _(input).countBy().entries().minBy(1)

console.info(_.head(result)) // or just result[0]
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Вы также можете сделать это с ES6 с Array.reduce, Array.sort и Object.entries:

const input = ["A", "A", "B", "B", "C"]

const countBy = arr => arr.reduce((r,c) => (r[c] = (r[c] || 0) + 1, r), {})
const min = arr => arr.sort((a,b) => a[1] - b[1])[0] // sort asc and take first
console.info(min(Object.entries(countBy(input)))[0])

Если вы не хотите импортировать все, что предлагает lodash, вы не можете использовать цепочку. Это версия Ответ Нины на основе _.flow():

const { flow, countBy, entries, partialRight, minBy, last, head } = _;

const input = ["A", "A", "B", "B", "C"];

const getByLowestCount = flow([
  countBy,
  entries,
  partialRight(minBy, last),
  head
]);

const result = getByLowestCount(input);

console.info(result);
<script src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

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