Подсчет вхождений / частоты элементов массива - PullRequest
184 голосов
/ 14 апреля 2011

В Javascript я пытаюсь взять начальный массив числовых значений и сосчитать элементы внутри него.В идеале, результатом должны быть два новых массива, первый из которых определяет каждый уникальный элемент, а второй содержит количество раз, которое встречается каждый элемент.Однако я открыт для предложений по формату вывода.

Например, если начальный массив был:

5, 5, 5, 2, 2, 2, 2, 2, 9, 4

Тогда будут созданы два новых массива.Первый будет содержать имя каждого уникального элемента:

5, 2, 9, 4

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

3, 5, 1, 1

Поскольку число 5 происходиттри раза в исходном массиве число 2 встречается пять раз, а 9 и 4 появляются один раз.

Я много искал решение, но, похоже, ничего не работает, и все, что я пробовал самв итоге оказался нелепо сложным.Любая помощь будет оценена!

Спасибо:)

Ответы [ 35 ]

1 голос
/ 19 апреля 2019

Вот самое простое решение

const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
let occurance_arr=[]; 
const aCount =  [...new Set(data)].map(x => {
   occurance_arr.push(data.filter(y=> y==x).length)
});
console.log(occurance_arr);   //[3, 5, 1, 1]
0 голосов
/ 14 июля 2019

Однолинейное решение ES6.Так много ответов, используя объект как карту, но я не вижу никого, кто бы использовал Карта

const map = arr.reduce((acc, e) => acc.set(e, acc.get(e) + 1 || 1), new Map());

Используйте map.keys(), чтобы получить уникальные элементы

Используйте map.values(), чтобы получить события

Я надеюсь, что хотя бы один человек найдет это полезным.

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]

const map = arr.reduce((acc, e) => acc.set(e, acc.get(e) + 1 || 1), new Map());

console.log(...map.keys())
console.log(...map.values())
0 голосов
/ 09 июля 2019

Этот вопрос более 8 лет , и многие, многие ответы на самом деле не учитывают ES6 и его многочисленные преимущества.

Возможно, еще более важно подумать о последствиях нашего кода для сбора мусора / управления памятью всякий раз, когда мы создаем дополнительные массивы, делаем двойные или тройные копии массивов или даже конвертируем массивы в объекты. Это тривиальные наблюдения для небольших приложений, но если масштаб является долгосрочной целью, подумайте об этом тщательно.

Если вам просто нужен «счетчик» для определенных типов данных, а отправной точкой является массив (поэтому я предполагаю, что вы хотите упорядоченный список и воспользоваться множеством свойств и методов, предлагаемых массивами), вы можете просто выполнить итерацию по массив1 и заполнить массив2 значениями и количеством вхождений для этих значений, найденных в массиве1.

Так просто.

Пример простого класса SimpleCounter (ES6) для Объектно-ориентированного программирования и Объектно-ориентированного проектирования

class SimpleCounter { 

    constructor(rawList){ // input array type
        this.rawList = rawList;
        this.finalList = [];
    }

    mapValues(){ // returns a new array

        this.rawList.forEach(value => {
            this.finalList[value] ? this.finalList[value]++ : this.finalList[value] = 1;
        });

        this.rawList = null; // remove array1 for garbage collection

        return this.finalList;

    }

}

module.exports = SimpleCounter;
0 голосов
/ 20 июня 2019
var aa = [1,3,5,7,3,2,4,6,8,1,3,5,5,2,0,6,5,9,6,3,5,2,5,6,8];
var newArray = {};
for(var element of aa){
  if(typeof newArray[element] === 'undefined' || newArray[element] === null){
    newArray[element] = 1;
  }else{
    newArray[element] +=1;
  }
}

for ( var element in newArray){
  console.log( element +" -> "+ newArray[element]);
}
0 голосов
/ 25 февраля 2019

Рабочий пример: https://jsfiddle.net/NChetanKumar/fuoxd6pg/

arr = [1,2,3,4,0,5,0,1,1,0,0];
function countOfRepeatednum(num,arr){
var count =0;
for(i=0;i<arr.length;i++){
if(arr[i] === num){
    count += 1;
}
}
console.log(count);
}
countOfRepeatednum(1,arr);
0 голосов
/ 27 марта 2019

Используя MAP , вы можете иметь 2 массива на выходе: один содержит вхождения, а другой - количество вхождений.

const dataset = [2,2,4,2,6,4,7,8,5,6,7,10,10,10,15];
let values = [];
let keys = [];

var mapWithOccurences = dataset.reduce((a,c) => {
  if(a.has(c)) a.set(c,a.get(c)+1);
  else a.set(c,1);
  return a;
}, new Map())
.forEach((value, key, map) => {
  keys.push(key);
  values.push(value);
});


console.log(keys)
console.log(values)
0 голосов
/ 02 марта 2013

Вы можете немного упростить это, расширив свои массивы функцией count.Он работает аналогично Ruby's Array#count, если вы с ним знакомы.

Array.prototype.count = function(obj){
  var count = this.length;
  if(typeof(obj) !== "undefined"){
    var array = this.slice(0), count = 0; // clone array and reset count
    for(i = 0; i < array.length; i++){
      if(array[i] == obj){ count++ }
    }
  }
  return count;
}

Использование:

let array = ['a', 'b', 'd', 'a', 'c'];
array.count('a'); // => 2
array.count('b'); // => 1
array.count('e'); // => 0
array.count(); // => 5

Суть


Редактировать

Затем вы можете получить свой первый массив с каждым возникшим элементом, используя Array#filter:

let occurred = [];
array.filter(function(item) {
  if (!occurred.includes(item)) {
    occurred.push(item);
    return true;
  }
}); // => ["a", "b", "d", "c"]

И свой второй массив счисло вхождений, используя Array#count в Array#map:

occurred.map(array.count.bind(array)); // => [2, 1, 1, 1]

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

let occurrences = {}
occurred.forEach(function(item) { occurrences[item] = array.count(item) });
occurences; // => {2: 5, 4: 1, 5: 3, 9: 1}
0 голосов
/ 06 декабря 2015

Я решал аналогичную проблему на codewars и разработал следующее решение, которое сработало для меня.

Это дает наибольшее количество целых в массиве, а также само целое число. Я думаю, что это может быть применено и к строковому массиву.

Чтобы правильно отсортировать строки, удалите function(a, b){return a-b} из sort() части

function mostFrequentItemCount(collection) {
    collection.sort(function(a, b){return a-b});
    var i=0;
    var ans=[];
    var int_ans=[];
    while(i<collection.length)
    {
        if(collection[i]===collection[i+1])
        {
            int_ans.push(collection[i]);
        }
        else
        {
            int_ans.push(collection[i]);
            ans.push(int_ans);
            int_ans=[];
        }
        i++;
    }

    var high_count=0;
    var high_ans;

    i=0;
    while(i<ans.length)
    {
        if(ans[i].length>high_count)
        {
            high_count=ans[i].length;
            high_ans=ans[i][0];
        }
        i++;
    }
    return high_ans;
}
0 голосов
/ 28 августа 2018
function countOcurrences(arr){
    return arr.reduce((aggregator, value, index, array) => {
      if(!aggregator[value]){
        return aggregator = {...aggregator, [value]: 1};  
      }else{
        return aggregator = {...aggregator, [value]:++aggregator[value]};
      }
    }, {})
}
0 голосов
/ 02 декабря 2018

Это легко с фильтром

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

let array = [{name: "steve", age: 22}, {name: "bob", age: 30}]

let count = array.filter(obj => obj.name === obj.name).length

console.log(count)

подробнее о JS Filiters здесь https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...