배열 요소의 발생 횟수 / 횟수 계산


216

Javascript에서는 숫자 값의 초기 배열을 가져 와서 그 안의 요소를 계산하려고합니다. 이상적으로 결과는 두 개의 새로운 배열이며, 첫 번째는 고유 한 각 요소를 지정하고 두 번째는 각 요소가 발생하는 횟수를 포함합니다. 그러나 나는 출력 형식에 대한 제안에 열려 있습니다.

예를 들어 초기 배열이 다음과 같은 경우

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

그런 다음 두 개의 새로운 배열이 생성됩니다. 첫 번째는 각 고유 요소의 이름을 포함합니다.

5, 2, 9, 4

두 번째는 요소가 초기 배열에서 발생한 횟수를 포함합니다.

3, 5, 1, 1

초기 배열에서 숫자 5가 3 번 발생하기 때문에 숫자 2는 5 번 발생하고 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)
Eshwar Prasad Yaddanapudi

arr.filter(x => x===5).length3배열에 '3'5가 있음을 나타 내기 위해 반환 됩니다.
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 다른 답변을 선호하십니까?
Šime Vidas

타사 라이브러리의 멋진 기본 프리미티브가 없으면 일반적으로 reduce답변 과 같이 구현합니다 . 이미 존재하기 전에 그러한 답변을 제출하려고했습니다. 그럼에도 불구하고 counts[num] = counts[num] ? counts[num]+1 : 1대답은 효과가있다 ( if(!result[a[i]])result[a[i]]=0답은 우아하지만 읽기 쉽지는 않다). 이 답변은 for 루프의 "더 나은"버전, 아마도 타사 for-loop를 사용하도록 수정할 수 있지만 표준 인덱스 기반 for-loops는 슬프게도 기본값이므로 무시합니다.
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]);

이제 counts 객체는 특정 숫자의 개수를 알려줍니다.

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

멤버 배열을 얻으려면 keys()함수를 사용하십시오.

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

3
Object.keys()기능은 IE9 +, FF4 +, SF5 +, CH6 +에서만 지원되지만 Opera는 지원하지 않습니다. 가장 큰 쇼 스토퍼는 IE9 + 라고 생각합니다 .
Robert Koritnik

19
마찬가지로, 나는 또한 좋아한다 counts[num] = (counts[num] || 0) + 1. 그렇게하면 counts[num]한 줄에 세 번이 아니라 두 번만 쓸 수 있습니다.
robru

1
이것은 좋은 대답입니다. 이것은 배열을 받아들이고 'counts'객체를 반환하는 함수로 쉽게 추상화됩니다.
bitsand

이것은 질문의 특정 예에 해당하지만 Google 직원을 위해 이것이 더 넓은 사용을 위해 항상 안전한 기술 은 아니라는 점을 지적하는 것이 좋습니다. 값을 계산하기 위해 값을 객체 키로 저장하면 해당 값을 문자열로 캐스팅 한 다음 해당 값을 계산합니다. [5, "5"]단순히 "5"두 번 있다고 말합니다 . 또는 인스턴스를 계산하면 다른 객체가 많이 있다는 것을 알 수 있습니다 [object Object]. 기타
Jimbo Jonny

그런 다음 반환 된 객체를 필터링하여 숫자에서 가장 높은 숫자 또는 가장 낮은 숫자 또는 가장 높은 숫자를 표시하는 방법
Ryan Holton

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

고마워, 아주 좋은 해결책;) ... 그리고 "key"와 "value"배열을 얻는 것 :const keys = Object.keys(a); const values = Object.values(a);
ncenerar

79

밑줄이나 lodash를 사용하는 경우 가장 간단한 방법입니다.

_.countBy(array);

그런 :

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

다른 사람들이 지적했듯이 결과 에서 _.keys()and _.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와의 2 차원 배열로 번역 [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. 또한 모든 값 / 유형이 핵심 역할을하도록하여이 솔루션이 객체 배열에서도 작동 함을 의미합니다.


우연히 객체 배열에 대한 이것에 대한 개선 된 대답이 있습니까? 객체 배열에 대해 수정하려고 시도하는 데 문제가 있습니다. 여기서 중복을 제거하는 새로운 배열 / 맵 / 세트를 만들고 객체에 새 값을 추가하십시오 (예 : "duplicatedCount : value"). 나는이 답변에서 내 중첩 된 객체 배열의 중복을 제거하기 위해 관리 stackoverflow.com/a/36744732
샤론을 구르

Set고유성을 위해 객체 참조를 사용하고 "유사한" 객체 를 비교하기위한 API를 제공하지 않습니다 . 이러한 작업에이 방법을 사용하려면 고유 한 인스턴스 배열을 보장하는 중간 축소 기능이 필요합니다. 가장 효율적이지 않지만 여기에 간단한 예를 정리했습니다 .
Emissary

답변 해주셔서 감사합니다! 하지만 실제로 약간 조금 다르게 해결했습니다. 내가 여기에 추가 한 답변을 볼 수 있다면 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

질문에 대답하지 않습니다.
Ry-

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()])


현대 자바 스크립트는 모든 세계에서 최고를 얻습니다
Igniter

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
콤마 연산자는 다음 이전을 반환, 이전 [CURR (또는 처음 상태는 1로)의 증가 때문에 값 「왼쪽에서 오른쪽 마지막 피연산자의 값을 반환 피연산자들의 각각을 평가한다. "
ChrisV

그러나 출력은 배열입니까?
Francesco

20

단일 라이너를 선호하는 경우.

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

편집 (6/12/2015) : 내부에서 설명. countMap은 단어를 빈도와 매핑하는 맵으로 익명 함수를 볼 수 있습니다. 축소하는 것은 모든 배열 요소와 countMap이 마지막 함수 호출의 반환 값으로 전달되는 인수와 함께 함수를 적용하는 것입니다. 마지막 매개 변수 ({})는 첫 번째 함수 호출에 대한 countMap의 기본값입니다.


1
이것을 설명해야합니다. 사람들이 다른 유스 케이스에서 사용하는 방법을 배울 수 있도록 훨씬 나은 답변을 만들 것입니다.
Andrew Grothe

단일 단지 일반적으로 수행 할 것 LINEBREAK을 제거 라이너 ;, {}. ... 확인. 나는 하나의 라이너에 대한 정의로 Conway의 Game of Life를 "oneliner"로 쓸 수 있다고 생각합니다.
trincot

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)

사용 가능한 경우 대부분 기본 자바 스크립트 함수로 설정됩니다.

데모 : 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}
쉬울 것입니다

JavaScript에서 한 줄로 무엇이든 할 수 있습니다.
Ry-

그리고 왜 나쁜가, @ Ry-?
ESL

때로는 여러 줄에서 더 명확하고 다른 줄은 한 줄에서 더 명확합니다. 그것은 "맛"의 문제입니다.
ESL

“ES6에서는 한 줄로 할 수 있습니다”는 모든 답변에 적용되며 ES5에서도 한 줄로 할 수 있습니다.
Ry-

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
질문은 모든 요소의 수를 요구했습니다.
Ry-

알았어. 지금 수정해야합니다.
ElDoRado1239

5

최신 자바 스크립트 기능을 사용하여 수행하는 방법은 다음과 같습니다.

먼저 배열을 Map카운트 중 하나로 줄입니다 .

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

를 사용하면 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];

또는 uniqueNums를 숫자로 사용하려는 경우

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())가져올 수 있습니다 . 모든 키 / 값을 2D 배열로 사용하여 큰 배열을 제공합니다. answer.keys()answer.values()[...answer]
Qaribou에서 조쉬

4

축소 (고정) 기능이있는 ES6 솔루션 :

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

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


하나의 숫자가 질문과 같은 개별 배열 요소의 수를 나타내는 방법을 잘 모릅니다.
Ry-

4

2020 편집 : 이것은 꽤 오래된 대답입니다 (9 년). 네이티브 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

람다가있는 내 솔루션 :

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

const counfFrequency = R.compose(
  R.map(R.length),
  R.groupBy(R.identity),
)

counfFrequency(testArray)

REPL에 연결하십시오.


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

나는 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

다음은 객체 배열 내에서 발생 횟수를 계산하는 방법입니다. 또한 첫 번째 배열의 내용을 새 배열 안에 배치하여 원래 배열의 순서가 중단되지 않도록 값을 정렬합니다. 그런 다음 재귀 함수를 사용하여 각 요소를 살펴보고 배열 내 각 개체의 수량 속성을 계산합니다.

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]};
      }
    }, {})
}

매번 객체를 복사하는 것은 매우 낭비입니다. 선형 일 수있는 이차 최악의 경우를 만듭니다.
Ry-

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와 그 많은 장점을 고려 하지는 않습니다 .

가비지 수집 / 메모리 관리를 위한 코드의 결과에 대해 생각하는 것이 훨씬 더 중요 할 것입니다추가 배열을 만들거나 배열의 이중 또는 삼중 복사본을 만들거나 배열을 객체로 변환 할 때마다 합니다. 이는 소규모 응용 분야에 대한 사소한 관찰이지만 규모가 장기적인 목표라면 철저하게 생각하십시오.

특정 데이터 유형에 대해 "카운터"가 필요하고 시작점이 배열 인 경우 (따라서 정렬 된 목록을 원하고 배열이 제공하는 많은 속성 및 메소드를 이용한다고 가정) 간단히 array1을 반복하고 채울 수 있습니다. array1에있는 이러한 값에 대한 값과 발생 횟수를 포함한 array2.

저것과 같이 쉬운.

객체 지향 프로그래밍객체 지향 설계를 위한 단순 클래스 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이지 않고 배열이 될 이유가 없으며, 올바르게 수행하는 것보다 이점이 없습니다.
Ry-

-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++;
    }
}

사전 순으로 결과를 원하면 먼저 정렬 할 수 있지만 데이터가 입력 된 순서를 유지하려면 시도해보십시오. 중첩 루프는이 페이지의 다른 방법보다 약간 느릴 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.