Підрахунок випадків / частоти елементів масиву


216

У Javascript я намагаюся взяти початковий масив значень чисел і підрахувати елементи всередині нього. В ідеалі результатом було б два нових масиви, перший вказує кожен унікальний елемент, а другий, що містить кількість разів кожного елемента. Однак я відкритий для пропозицій щодо формату виводу.

Наприклад, якщо початковий масив був:

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

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

5, 2, 9, 4

Другий міститиме кількість разів, коли цей елемент траплявся в початковому масиві:

3, 5, 1, 1

Оскільки число 5 трапляється тричі в початковому масиві, число 2 відбувається п'ять разів, а 9 і 4 з'являються один раз.

Я багато шукав рішення, але, здається, нічого не працює, і все, що я спробував на собі, виявилося смішно складним. Будь-яка допомога буде вдячна!

Дякую :)


8
Якщо все, що вам потрібно, було зрозуміти, чи з’являється значення лише один раз (замість двох і більше разів), ви можете використовуватиif (arr.indexOf(value) == arr.lastIndexOf(value))
Rodrigo

1
Ми можемо використати 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" п'яти.
noobninja

Відповіді:


94

Ось вам:

function foo(arr) {
    var a = [], b = [], prev;

    arr.sort();
    for ( var i = 0; i < arr.length; i++ ) {
        if ( arr[i] !== prev ) {
            a.push(arr[i]);
            b.push(1);
        } else {
            b[b.length-1]++;
        }
        prev = arr[i];
    }

    return [a, b];
}

Демо-версія: http://jsfiddle.net/simevidas/bnACW/

Примітка

Це змінює порядок вихідного масиву вводу за допомогою Array.sort


24
є побічний ефект сортування масиву (побічні ефекти погані), також сортування є, O(N log(N))а посилення елегантності не варто
ninjagecko

1
@ninja Яку іншу відповідь ви віддаєте перевагу?
Шіме Відас

За відсутності приємного примітиву високого рівня у сторонній бібліотеці, я б зазвичай реалізував це, як reduceвідповідь. Я збирався подати таку відповідь ще до того, як побачив, що вона вже існує. Тим не менш, counts[num] = counts[num] ? counts[num]+1 : 1відповідь також працює (рівнозначно if(!result[a[i]])result[a[i]]=0відповіді, яка є більш елегантною, але менш легкою для читання); ці відповіді можуть бути змінені для використання "приємнішої" версії циклу for, можливо, стороннього для-циклу, але я начебто ігнорував, що оскільки стандартні для-циклів на основі індексу, на жаль, за замовчуванням.
ninjagecko

2
@ninja Я згоден Ці відповіді кращі. На жаль, я не можу не прийняти власну відповідь.
Šime Vidas

Для невеликих масивів сортування його на місці може бути швидшим, ніж створення асоціативного масиву.
Quant_dev

219

Ви можете використовувати об'єкт для проведення результатів:

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counts = {};

for (var i = 0; i < arr.length; i++) {
  var num = arr[i];
  counts[num] = counts[num] ? counts[num] + 1 : 1;
}

console.log(counts[5], counts[2], counts[9], counts[4]);

Отже, тепер об'єкт підрахунку може сказати вам, що рахується для певного числа:

console.log(counts[5]); // logs '3'

Якщо ви хочете отримати масив членів, просто скористайтеся keys()функціями

keys(counts); // returns ["5", "2", "9", "4"]

3
Слід зазначити, що ця Object.keys()функція підтримується лише в IE9 +, FF4 +, SF5 +, CH6 +, але Opera її не підтримує. Я думаю, що найбільший пробник шоу - IE9 + .
Роберт Коритник

19
Так само мені подобається counts[num] = (counts[num] || 0) + 1. Таким чином, вам потрібно написати лише counts[num]двічі замість трьох разів на одному рядку.
robru

1
Це приємна відповідь. Це легко абстрагується у функції, яка приймає масив і повертає об'єкт 'counts'.
bitsand

Це стосується конкретного прикладу у питанні, але заради гуглерів варто зазначити, що це не завжди безпечна техніка для широкого використання. Збереження значень як об’єктних ключів для їх підрахунку означає, що ви кидаєте ці значення в рядки і потім підраховуєте це значення. [5, "5"]просто скажу, що у вас "5"два рази. Або підрахунок випадків деяких різних об'єктів просто скаже вам, що їх багато [object Object]. І т. Д.
Jimbo Jonny

Як я міг потім фільтрувати повернутий об’єкт, щоб показати мені найвищий до найнижчого або найнижчий за найвищим рахунком у числах
Райан Холтон

92
var a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].reduce(function (acc, curr) {
  if (typeof acc[curr] == 'undefined') {
    acc[curr] = 1;
  } else {
    acc[curr] += 1;
  }

  return acc;
}, {});

// a == {2: 5, 4: 1, 5: 3, 9: 1}

39
acc[curr] ? acc[curr]++ : acc[curr] = 1;
pmandell

Дякую, дуже приємне рішення;) ... і отримати масиви "ключ" та "значення":const keys = Object.keys(a); const values = Object.values(a);
ncenerar

79

Якщо ви використовуєте підкреслення або подачу, це зробити найпростіше:

_.countBy(array);

Такий, що:

_.countBy([5, 5, 5, 2, 2, 2, 2, 2, 9, 4])
=> Object {2: 5, 4: 1, 5: 3, 9: 1}

Як вказували інші, ви можете потім виконати функції _.keys()та _.values()функції в результаті, щоб отримати лише унікальні числа та їх виникнення відповідно. Але на мій досвід, з оригінальним предметом набагато простіше впоратися.


55

Не використовуйте два масиви для результату, використовуйте об'єкт:

a      = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
result = { };
for(var i = 0; i < a.length; ++i) {
    if(!result[a[i]])
        result[a[i]] = 0;
    ++result[a[i]];
}

Тоді resultбуде виглядати так:

{
    2: 5,
    4: 1,
    5: 3,
    9: 1
}

47

Як щодо варіанта ECMAScript2015

const a = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

const aCount = new Map([...new Set(a)].map(
    x => [x, a.filter(y => y === x).length]
));
aCount.get(5)  // 3
aCount.get(2)  // 5
aCount.get(9)  // 1
aCount.get(4)  // 1

Цей приклад передає вхідний масив Setконструктору, створюючи набір унікальних значень. Синтаксис поширення потім розширює ці значення в новий масив таким чином , ми можемо назвати mapі перевести це в двовимірний масив з [value, count]пар - тобто такої структури:

Array [
   [5, 3],
   [2, 5],
   [9, 1],
   [4, 1]
]

Потім новий масив передається Mapконструктору, що призводить до ітерабельного об'єкта:

Map {
    5 => 3,
    2 => 5,
    9 => 1,
    4 => 1
}

Чудова річ у Mapоб’єкті полягає в тому, що він зберігає типи даних - тобто aCount.get(5)повернеться, 3але aCount.get("5")повернеться undefined. Це також дозволяє будь-якому значенню / типу виконувати роль ключового значення. Це рішення також буде працювати з масивом об'єктів.


чи є у вас випадково вдосконалена відповідь на це лише для масиву об'єктів? у них виникають проблеми при спробі змінити його для об’єктного масиву, де ви просто створите новий масив / карту / набір, з якого ви видалите дублікати, і додасте нове значення для об'єкта, скажімо, під назвою "duplicateCount: value". мені вдалося видалити дублікати з мого вкладеного масиву об’єктів з цієї відповіді stackoverflow.com/a/36744732
sharon gur

Setвикористовує посилання на об'єкти для унікальності та не пропонує API для порівняння "подібних" об'єктів. Якщо ви хочете використовувати цей підхід для такого завдання, вам знадобиться функція проміжного скорочення, яка гарантує масив унікальних примірників. Це не найефективніше, але я зібрав тут короткий приклад .
Емісар

Дякую за відповідь! але я насправді вирішив це ліфтом трохи інакше. якщо ви можете побачити відповідь, яку я додав сюди stackoverflow.com/a/43211561/4474900, я дав приклад того, що я зробив. він працює добре, у моєму випадку був складний об'єкт, необхідний для порівняння. не знаю про ефективність мого рішення, хоча
sharon gur

8
Це може використовувати хороші нові структури даних, але має час виконання в O ( ), хоча тут існує маса простих алгоритмів, які вирішують це в O ( n ).
raphinesse

41

Я думаю, що це найпростіший спосіб підрахунку подій з однаковим значенням у масиві.

var a = [true, false, false, false];
a.filter(function(value){
    return value === false;
}).length

9
або a.filter(value => !value).lengthз новим синтаксисом js
t3chb0t

Не відповідає на запитання.
Ри-

35

Одне рядкове рішення ES6. Так багато відповідей, використовуючи об’єкт як карту, але я не можу побачити того, хто використовує фактичну Карта

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

Використовуйте map.keys()для отримання унікальних елементів

Використовуйте map.values()для отримання подій

Використовуйте map.entries()для отримання пар [елемент, частота]

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

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

console.info([...map.keys()])
console.info([...map.values()])
console.info([...map.entries()])


Сучасний Javascript отримує найкраще з усіх світів
запальник

30

const data = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]

function count(arr) {
  return arr.reduce((prev, curr) => (prev[curr] = ++prev[curr] || 1, prev), {})
}

console.log(count(data))


4
Хтось би потурбував би пояснити це (prev [curr] = ++ prev [curr] || 1, prev)?
Souljacker

6
Оператор комами "оцінює кожен з його операндів (зліва направо) і повертає значення останнього операнда", тому це збільшує значення prev [curr] (або ініціалізує його до 1), потім повертає prev.
ChrisV

але чи є вихід масивом?
Франческо

20

Якщо ви віддаєте перевагу одному вкладишу.

arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});

Редагувати (12.12.2015) : Пояснення зсередини. countMap - це карта, яка відображає слово з його частотою, на якій ми можемо бачити анонімну функцію. Що таке зменшення, це застосувати функцію з аргументами, оскільки всі елементи масиву і countMap передаються як значення повернення останнього виклику функції. Останній параметр ({}) - це значення за замовчуванням countMap для першого виклику функції.


1
Ви повинні пояснити це. це зробить це набагато кращою відповіддю, щоб люди могли навчитися використовувати його в інших випадках використання.
Ендрю Гроте

Єдиний вкладиш, який просто видаляє рядок рядка, який зазвичай слід ;, {і }. ... ГАРАЗД. Я думаю, що з таким визначенням одного лайнера ми можемо написати «Гра життя» Конвея як «однолінійку».
трінкот

16

Версія ES6 повинна бути значно спрощеною (ще одне лінійне рішення)

let arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
let acc = arr.reduce((acc, val) => acc.set(val, 1 + (acc.get(val) || 0)), new Map());

console.log(acc);
// output: Map { 5 => 3, 2 => 5, 9 => 1, 4 => 1 }

Карта замість простого Об'єкта допомагає нам розрізняти різні типи елементів, інакше все підрахунок базується на рядках


8

Якщо ви використовуєте підкреслення, ви можете піти функціональним шляхом

a = ['foo', 'foo', 'bar'];

var results = _.reduce(a,function(counts,key){ counts[key]++; return counts },
                  _.object( _.map( _.uniq(a), function(key) { return [key, 0] })))

тому ваш перший масив є

_.keys(results)

а другий масив -

_.values(results)

більша частина цього буде за замовчуванням для власних функцій JavaScript, якщо вони доступні

демо: http://jsfiddle.net/dAaUU/


8

На підставі відповіді на @adamse і @pmandell (який я upvote), в ES6 ви можете зробити це в одному рядку :

  • Редагування 2017 року : я використовую, ||щоб зменшити розмір коду та зробити його більш читабельним.

var a=[7,1,7,2,2,7,3,3,3,7,,7,7,7];
alert(JSON.stringify(

a.reduce((r,k)=>{r[k]=1+r[k]||1;return r},{})

));


Його можна використовувати для підрахунку символів :

var s="ABRACADABRA";
alert(JSON.stringify(

s.split('').reduce((a, c)=>{a[c]++?0:a[c]=1;return a},{})

));


Це було б читабельніше, якби ви використовували || 0:(r,k)=>{r[k]=(r[k]||0)+1;return r}
12Me21

Ви можете робити що-небудь в одному рядку в JavaScript.
Ри-

І чому це погано, @ Ry-?
ESL

Іноді це чіткіше в декількох рядках, інше - чіткіше в одному рядку. Але це справа "смаку".
ESL

Я маю на увазі, що "в ES6 ти можеш це зробити в одному рядку" стосується кожної відповіді, і ти також можеш зробити це в ES5 в одному рядку.
Ри-

5

Ось просто щось легке і легке для очей ...

function count(a,i){
 var result = 0;
 for(var o in a)
  if(a[o] == i)
   result++;
 return result;
}

Редагувати: І оскільки ви хочете всіх випадків ...

function count(a){
 var result = {};
 for(var i in a){
  if(result[a[i]] == undefined) result[a[i]] = 0;
  result[a[i]]++;
 }
 return result;
}

1
У питанні було задано підрахунок усіх елементів.
Ри-

Гаразд, пропустив це. Слід виправити зараз.
ElDoRado1239

5

Ось ось як я це зробив би з деякими найновішими функціями javascript:

Спочатку зменшіть масив до Mapчисла a :

let countMap = array.reduce(
  (map, value) => {map.set(value, (map.get(value) || 0) + 1); return map}, 
  new Map()
)

Використовуючи a Map, ваш початковий масив може містити будь-який тип об'єктів, і підрахунки будуть правильними. Без цього Mapдеякі типи об’єктів дадуть вам дивні показники. Докладнішу інформацію про відмінності див. У Mapдокументах .

Це також можна зробити з об'єктом, якщо всі ваші значення - це символи, числа чи рядки:

let countObject = array.reduce(
  (map, value) => { map[value] = (map[value] || 0) + 1; return map },
  {}
)

Або трохи фантазувати функціонально без мутації, використовуючи деструктування та синтаксис розповсюдження об'єктів:

let countObject = array.reduce(
  (value, {[value]: count = 0, ...rest}) => ({ [value]: count + 1, ...rest }),
  {}
)

На цьому етапі ви можете використовувати Mapабо об'єкт для своїх рахунків (і карта є безпосередньо ітерабельною, на відміну від об'єкта), або перетворити його на два масиви.

Для Map:

countMap.forEach((count, value) => console.log(`value: ${value}, count: ${count}`)

let values = countMap.keys()
let counts = countMap.values()

Або для об'єкта:

Object
  .entries(countObject) // convert to array of [key, valueAtKey] pairs
  .forEach(([value, count]) => console.log(`value: ${value}, count: ${count}`)

let values = Object.keys(countObject)
let counts = Object.values(countObject)

4
var array = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

function countDuplicates(obj, num){
  obj[num] = (++obj[num] || 1);
  return obj;
}

var answer = array.reduce(countDuplicates, {});
// answer => {2:5, 4:1, 5:3, 9:1};

Якщо ви все ще хочете два масиви, то ви можете використовувати відповідь, як це ...

var uniqueNums = Object.keys(answer);
// uniqueNums => ["2", "4", "5", "9"];

var countOfNums = Object.keys(answer).map(key => answer[key]);
// countOfNums => [5, 1, 3, 1];

Або якщо ви хочете, щоб унікальніNum були числами

var uniqueNums = Object.keys(answer).map(key => +key);
// uniqueNums => [2, 4, 5, 9];

1
es6 / 7 робить це все набагато приємніше. Ви також можете скористатися Mapзамість цього, оскільки це дозволить уникнути набору тексту, який використовує число в якості об'єктного ключа (кастинг як рядок). const answer = array.reduce((a, e) => a.set(e, (a.get(e) || 0) + 1), new Map()).Ви можете отримати answer.keys()як ключі, так і answer.values()значення як масиви. [...answer]дасть вам великий масив з усіма ключами / значеннями як 2d масиви.
Джош з Карібу

4

Рішення ES6 із зменшенням (фіксованим):

const arr = [2, 2, 2, 3, 2]

const count = arr.reduce((pre, cur) => (cur === 2) ? ++pre : pre, 0)
console.log(count) // 4


Не впевнено, як одне число відображає кількість кожного окремого елемента масиву, як запитання.
Ри-

4

Редагувати 2020 : це досить стара відповідь (дев'ять років). Розширення рідного prototypeзавжди породжує дискусію . Хоча я думаю, що програміст вільний обирати власний стиль програмування, ось (більш сучасний) підхід до проблеми, не поширюючись Array.prototype:

{
  // create array with some pseudo random values (1 - 5)
  const arr = Array.from({length: 100})
    .map( () => Math.floor(1 + Math.random() * 5) );
  // frequencies using a reducer
  const arrFrequencies = arr.reduce((acc, value) => 
      ({ ...acc, [value]: acc[value] + 1 || 1}), {} )
  console.log(`Value 4 occurs ${arrFrequencies[4]} times in arrFrequencies`);

  // bonus: restore Array from frequencies
  const arrRestored = Object.entries(arrFrequencies)
    .reduce( (acc, [key, value]) => acc.concat(Array(value).fill(+key)), [] );
  console.log(arrRestored.join());  
}
.as-console-wrapper { top: 0; max-height: 100% !important; }

Стара відповідь (2011 р.): Ви можете продовжити Array.prototype, як це:



2

Розв’язання за допомогою карти з O (n) часовою складністю.

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

const countOccurrences = (arr) => {
    const map = {};
    for ( var i = 0; i < arr.length; i++ ) {
        map[arr[i]] = ~~map[arr[i]] + 1;
    }
    return map;
}

Демо: http://jsfiddle.net/simevidas/bnACW/


Моє звернення до вас, це працює як масло з O (n) складністю часу
Vishal Shetty


1

Використовуючи 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

Перегляньте код нижче.

<html>
<head>
<script>
// array with values
var ar = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];

var Unique = []; // we'll store a list of unique values in here
var Counts = []; // we'll store the number of occurances in here

for(var i in ar)
{
    var Index = ar[i];
    Unique[Index] = ar[i];
    if(typeof(Counts[Index])=='undefined')  
        Counts[Index]=1;
    else
        Counts[Index]++;
}

// remove empty items
Unique = Unique.filter(function(){ return true});
Counts = Counts.filter(function(){ return true});

alert(ar.join(','));
alert(Unique.join(','));
alert(Counts.join(','));

var a=[];

for(var i=0; i<Unique.length; i++)
{
    a.push(Unique[i] + ':' + Counts[i] + 'x');
}
alert(a.join(', '));

</script>
</head>
<body>

</body>
</html>

0

Спробуйте це:

Array.prototype.getItemCount = function(item) {
    var counts = {};
    for(var i = 0; i< this.length; i++) {
        var num = this[i];
        counts[num] = counts[num] ? counts[num]+1 : 1;
    }
    return counts[item] || 0;
}

0

Я вирішував подібну проблему на кодових машинах і розробляв наступне рішення, яке працювало для мене.

Це дає найбільшу кількість цілого числа в масиві, а також саме ціле число. Я думаю, що це може бути застосовано і до рядкового масиву.

Для правильного сортування рядків, зніміть 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

Ось спосіб порахувати події всередині масиву об’єктів. Він також розміщує вміст першого масиву всередині нового масиву для сортування значень, щоб порядок у вихідному масиві не був порушений. Потім використовується рекурсивна функція для проходження кожного елемента та підрахунку властивості кількості кожного об'єкта всередині масиву.

var big_array = [
  { name: "Pineapples", quantity: 3 },
  { name: "Pineapples", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Limes", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Pineapples", quantity: 2 },
  { name: "Pineapples", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Bananas", quantity: 1 },
  { name: "Bananas", quantity: 5 },
  { name: "Coconuts", quantity: 1 },
  { name: "Lemons", quantity: 2 },
  { name: "Oranges", quantity: 1 },
  { name: "Lemons", quantity: 1 },
  { name: "Limes", quantity: 1 },
  { name: "Grapefruit", quantity: 1 },
  { name: "Coconuts", quantity: 5 },
  { name: "Oranges", quantity: 6 }
];

function countThem() {
  var names_array = [];
  for (var i = 0; i < big_array.length; i++) {
    names_array.push( Object.assign({}, big_array[i]) );
  }

  function outerHolder(item_array) {
    if (item_array.length > 0) {
      var occurrences = [];
      var counter = 0;
      var bgarlen = item_array.length;
      item_array.sort(function(a, b) { return (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0); });

      function recursiveCounter() {
        occurrences.push(item_array[0]);
        item_array.splice(0, 1);
        var last_occurrence_element = occurrences.length - 1;
        var last_occurrence_entry = occurrences[last_occurrence_element].name;
        var occur_counter = 0;
        var quantity_counter = 0;
        for (var i = 0; i < occurrences.length; i++) {
          if (occurrences[i].name === last_occurrence_entry) {
            occur_counter = occur_counter + 1;
            if (occur_counter === 1) {
              quantity_counter = occurrences[i].quantity;
            } else {
              quantity_counter = quantity_counter + occurrences[i].quantity;
            }
          }
        }

        if (occur_counter > 1) {
          var current_match = occurrences.length - 2;
          occurrences[current_match].quantity = quantity_counter;
          occurrences.splice(last_occurrence_element, 1);
        }

        counter = counter + 1;

        if (counter < bgarlen) {
          recursiveCounter();
        }
      }

      recursiveCounter();

      return occurrences;
    }
  }
  alert(JSON.stringify(outerHolder(names_array)));
}

0
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
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

Це питання більше 8 років, і багато, багато відповідей насправді не враховують ES6 та його численні переваги.

Можливо, ще важливіше думати про наслідки нашого коду для вивезення сміття / управління пам’яттю коли ми створюємо додаткові масиви, робимо подвійні чи потрійні копії масивів або навіть перетворюємо масиви в об’єкти. Це банальні спостереження для невеликих застосувань, але якщо масштаб є довгостроковою метою, то подумайте про це ретельно.

Якщо вам просто потрібен "лічильник" для конкретних типів даних, а початковою точкою є масив (я вважаю, ви хочете, таким чином, впорядкований список і скористатися багатьма пропозиціями масивів властивостей та методів), ви можете просто просто перебрати через масив1 та заповнити array2 зі значеннями та кількістю входів для цих значень, знайдених у масиві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;

Якщо дотримуватися функції в класі без будь-якої причини, це не робить її об'єктно-орієнтованою, finalListне має підстав бути масивом, і це не має переваг перед її правильним виконанням.
Ри-

-1

Ось класичний метод старої школи для підрахунку масивів.

var arr = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4];
var counted = [], count = [];
var i = 0, j = 0, k = 0;
while (k < arr.length) {
    if (counted.indexOf(arr[k]) < 0) {
        counted[i] = arr[k];
        count[i] = 0;
        for (j = 0; j < arr.length; j++) {
            if (counted[i] == arr[j]) {
                count[i]++;
            }
        }
        i++;
    } else {
        k++;
    }
}

Ви можете спершу відсортувати його, якщо потрібно алфавітний результат, але якщо ви хочете зберегти порядок введення даних, спробуйте це спробувати. Вкладені петлі можуть бути трохи повільнішими, ніж деякі інші методи на цій сторінці.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.