В Javascript я пытаюсь взять начальный массив числовых значений и подсчитать элементы внутри него. В идеале, результатом должны быть два новых массива, первый из которых определяет каждый уникальный элемент, а второй содержит количество раз, которое каждый элемент встречается. Тем не менее, я открыт для предложений по формату вывода.
Например, если исходный массив был:
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
Затем будут созданы два новых массива. Первый будет содержать имя каждого уникального элемента:
5, 2, 9, 4
Второй будет содержать количество раз, когда этот элемент встречается в исходном массиве:
3, 5, 1, 1
Поскольку число 5 встречается три раза в исходном массиве, число 2 встречается пять раз, а 9 и 4 оба появляются один раз.
Я много искал решение, но, похоже, ничего не работает, и все, что я пробовал сам, оказалось до смешного сложным. Любая помощь будет оценена!
Спасибо :)
источник
if (arr.indexOf(value) == arr.lastIndexOf(value))
ramda.js
для достижения этого простым способом.const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
arr.filter(x => x===5).length
возвратился бы,3
чтобы указать, что есть '3' пятерки в массиве.Ответы:
Ну вот:
Демоверсия в реальном времени: http://jsfiddle.net/simevidas/bnACW/
источник
O(N log(N))
и выигрыш в элегантности не стоитreduce
ответ. Я собирался представить такой ответ, прежде чем увидел, что он уже существует. Тем не менее,counts[num] = counts[num] ? counts[num]+1 : 1
ответ также работает (эквивалентноif(!result[a[i]])result[a[i]]=0
ответу, который более элегантен, но менее удобен для чтения); эти ответы можно изменить, чтобы использовать «более приятную» версию цикла for, возможно, сторонний цикл for, но я как бы проигнорировал это, поскольку стандартные циклы for на основе индекса, к сожалению, используются по умолчанию.Вы можете использовать объект для хранения результатов:
Итак, теперь ваш объект count может сказать вам, что это за счет для определенного числа:
Если вы хотите получить массив членов, просто используйте
keys()
функцииисточник
Object.keys()
функция поддерживается только в IE9 +, FF4 +, SF5 +, CH6 +, но Opera не поддерживает ее. Я думаю, что самая большая пробка шоу здесь IE9 + .counts[num] = (counts[num] || 0) + 1
. Таким образом, вам нужно всего лишь написатьcounts[num]
дважды вместо трех раз в этой строке.[5, "5"]
просто скажу, у вас есть"5"
два раза. Или подсчет экземпляров различных объектов просто скажет вам, что их много[object Object]
. И т.д. и т.п.источник
acc[curr] ? acc[curr]++ : acc[curr] = 1;
const keys = Object.keys(a);
const values = Object.values(a);
Если вы используете подчеркивание или lodash, это самое простое:
Такой что:
Как указывалось другими, вы можете затем выполнить команду меню
_.keys()
и_.values()
функции на результат , чтобы получить только уникальные номера, и их вхождения соответственно. Но по моему опыту, с оригинальным объектом гораздо проще иметь дело.источник
Не используйте два массива для результата, используйте объект:
Тогда
result
будет выглядеть так:источник
Как насчет опции ECMAScript2015.
Этот пример передает входной массив в
Set
конструктор, создавая коллекцию уникальных значений. Синтаксис распространения затем расширяет эти значения в новый массив таким образом , мы можем назватьmap
и перевести это в двумерный массив из[value, count]
пар - т.е. следующей структуры:Новый массив затем передается в
Map
конструктор, в результате чего получается итеративный объект:Самое замечательное в
Map
объекте состоит в том, что он сохраняет типы данных - то естьaCount.get(5)
будет возвращаться,3
ноaCount.get("5")
будет возвращатьсяundefined
. Это также позволяет любому значению / типу действовать как ключ, означающий, что это решение также будет работать с массивом объектов.Показать фрагмент кода
источник
Set
использует ссылки на объекты для уникальности и не предлагает API для сравнения «похожих» объектов. Если вы хотите использовать этот подход для такой задачи, вам понадобится некоторая промежуточная функция сокращения, которая гарантирует массив уникальных экземпляров. Это не самый эффективный, но я собрал небольшой пример здесь .Я думаю, что это самый простой способ подсчета вхождений с одинаковым значением в массиве.
источник
a.filter(value => !value).length
с новым синтаксисом jsОднолинейное решение ES6. Так много ответов, используя объект в качестве карты, но я не вижу никого, кто использует настоящую карту
Используйте,
map.keys()
чтобы получить уникальные элементыИспользуйте,
map.values()
чтобы получить вхожденияИспользуйте,
map.entries()
чтобы получить пары [элемент, частота]источник
источник
Если вы предпочитаете один лайнер.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
Изменить (12.06.2015) : объяснение изнутри. countMap - это карта, которая отображает слово с его частотой, которую мы видим в анонимной функции. Что уменьшает, так это применяет функцию с аргументами в качестве всех элементов массива и countMap, передаваемых в качестве возвращаемого значения последнего вызова функции. Последний параметр ({}) является значением по умолчанию countMap для первого вызова функции.
источник
;
,{
и}
. ... ХОРОШО. Я думаю, что с этим определением одного лайнера мы можем написать «Игру жизни» Конвея как «лайнер».Версия ES6 должна быть намного проще (еще одно решение линии)
Карта вместо простого Объекта помогает нам различать различные типы элементов, иначе все подсчеты основаны на строках
источник
Если вы используете подчеркивание, вы можете пойти функциональным путем
так что ваш первый массив
и второй массив
большинство из них по умолчанию будут использовать нативные функции javascript, если они доступны
демо: http://jsfiddle.net/dAaUU/
источник
На основании ответа на @adamse и @pmandell (который я upvote), в ES6 вы можете сделать это в одной строке :
||
чтобы уменьшить размер кода и сделать его более читабельным.Может использоваться для подсчета символов :
источник
|| 0
:(r,k)=>{r[k]=(r[k]||0)+1;return r}
Вот только что-то легкое и легкое для глаз ...
Редактировать: И так как вы хотите все случаи ...
источник
Итак, вот как я могу сделать это с некоторыми из новейших функций JavaScript:
Во-первых, уменьшите массив до
Map
числа:Используя
Map
, ваш начальный массив может содержать любой тип объекта, и количество будет правильным. БезMap
некоторых типов объектов вы получите странное количество. СмотритеMap
документы для получения дополнительной информации о различиях.Это также может быть сделано с объектом, если все ваши значения являются символами, числами или строками:
Или немного более функционально без мутаций, используя деструктуризацию и синтаксис распространения объектов:
На этом этапе вы можете использовать
Map
объект или для подсчета (и карта является итеративной, в отличие от объекта) или преобразовать ее в два массива.Для
Map
:Или для объекта:
источник
источник
Map
Вместо этого вы можете захотеть уменьшить значение до , так как это позволит избежать приведения типов к типу , который использует число в качестве ключа объекта (приведение в виде строки).const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map())
.Вы можете получитьanswer.keys()
для ключей, аanswer.values()
для значений в виде массивов.[...answer]
даст вам большой массив со всеми ключами / значениями в виде 2d массивов.Решение ES6 с уменьшением (фиксированным):
источник
Изменить 2020 : это довольно старый ответ (девять лет). Расширение нативного языка
prototype
всегда вызывает дискуссию . Хотя я думаю, что программист может свободно выбирать свой собственный стиль программирования, вот (более современный) подход к проблеме без расширенияArray.prototype
:Старый (2011) ответ: вы могли бы расширить
Array.prototype
, как это:Показать фрагмент кода
источник
Мое решение с рамдой:
Ссылка на REPL.
источник
Решение с использованием карты с O (n) сложностью по времени.
Демо: http://jsfiddle.net/simevidas/bnACW/
источник
Существует гораздо лучший и простой способ, которым мы можем сделать это, используя
ramda.js
. Пример кода здесьconst ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
countBy документация находится в документацииисточник
Используя MAP, вы можете иметь 2 массива в выходных данных: один содержит вхождения, а другой - количество вхождений.
источник
Проверьте код ниже.
источник
Попробуй это:
источник
Я решал аналогичную проблему на codewars и разработал следующее решение, которое сработало для меня.
Это дает наибольшее количество целых в массиве, а также само целое число. Я думаю, что это может быть применено и к строковому массиву.
Чтобы правильно отсортировать строки, удалите
function(a, b){return a-b}
изнутриsort()
частьисточник
Вот способ подсчета вхождений внутри массива объектов. Он также помещает содержимое первого массива в новый массив для сортировки значений, чтобы порядок в исходном массиве не нарушался. Затем используется рекурсивная функция для прохождения каждого элемента и подсчета количественного свойства каждого объекта в массиве.
источник
источник
источник
Этому вопросу более 8 лет, и многие, многие ответы на самом деле не учитывают ES6 и его многочисленные преимущества.
Возможно, еще важнее думать о последствиях нашего кода для сбора мусора / управления памятью всякий раз, когда мы создаем дополнительные массивы, делаем двойные или тройные копии массивов или даже конвертируем массивы в объекты. Это тривиальные наблюдения для небольших приложений, но если масштаб является долгосрочной целью, подумайте об этом тщательно.
Если вам просто нужен «счетчик» для определенных типов данных, а отправной точкой является массив (поэтому я предполагаю, что вы хотите упорядоченный список и воспользоваться множеством свойств и методов, предлагаемых массивами), вы можете просто перебрать массив1 и заполнить массив2 со значениями и количеством вхождений для этих значений, найденных в массиве1.
Так просто, как, что.
Пример простого класса SimpleCounter (ES6) для объектно-ориентированного программирования и объектно-ориентированного проектирования
источник
finalList
нее нет причины быть массивом, и это не имеет никаких преимуществ по сравнению с ее правильной работой.Вот классический метод старой школы для подсчета массивов.
Вы можете сначала отсортировать их, если хотите получить алфавитный результат, но если вы хотите сохранить порядок, в котором были введены данные, попробуйте. Вложенные циклы могут быть немного медленнее, чем некоторые другие методы на этой странице.
источник