배열 요소의 발생 횟수 / 횟수 계산
Javascript에서는 숫자 값의 초기 배열을 가져 와서 그 안의 요소를 계산하려고합니다. 이상적으로 결과는 두 개의 새로운 배열이며, 첫 번째는 고유 한 각 요소를 지정하고 두 번째는 각 요소의 발생 횟수를 포함합니다. 그러나 나는 출력 형식에 대한 제안에 열려 있습니다.
예를 들어 초기 배열이 다음과 같은 경우
5, 5, 5, 2, 2, 2, 2, 2, 9, 4
그런 다음 두 개의 새로운 배열이 생성됩니다. 첫 번째는 각 고유 요소의 이름을 포함합니다.
5, 2, 9, 4
두 번째는 요소가 초기 배열에서 발생한 횟수를 포함합니다.
3, 5, 1, 1
초기 배열에서 숫자 5는 세 번 발생하기 때문에 숫자 2는 다섯 번 발생하고 9와 4는 모두 한 번 나타납니다.
나는 해결책을 많이 찾았지만 아무것도 효과가없는 것 같습니다. 내가 시도한 모든 것이 엄청나게 복잡해졌습니다. 도움을 주시면 감사하겠습니다!
감사 :)
여기 있습니다 :
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
객체를 사용하여 결과를 보유 할 수 있습니다.
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"]
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}
밑줄이나 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()
함수 를 실행 하여 고유 숫자와 그 발생을 각각 얻을 수 있습니다. 그러나 내 경험상 원래의 객체는 다루기가 훨씬 쉽습니다.
결과에 두 개의 배열을 사용하지 말고 객체를 사용하십시오.
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
}
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
합니다. 또한 모든 값 / 유형이 핵심 역할을하도록하여이 솔루션이 객체 배열에서도 작동 함을 의미합니다.
function frequencies(/* {Array} */ a){
return new Map([...new Set(a)].map(
x => [x, a.filter(y => y === x).length]
));
}
let foo = { value: 'foo' },
bar = { value: 'bar' },
baz = { value: 'baz' };
let aNumbers = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4],
aObjects = [foo, bar, foo, foo, baz, bar];
frequencies(aNumbers).forEach((val, key) => console.log(key + ': ' + val));
frequencies(aObjects).forEach((val, key) => console.log(key.value + ': ' + val));
이것이 배열에서 동일한 값으로 발생을 계산하는 가장 간단한 방법이라고 생각합니다.
var a = [true, false, false, false];
a.filter(function(value){
return value === false;
}).length
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))
단일 라이너를 선호하는 경우.
arr.reduce(function(countMap, word) {countMap[word] = ++countMap[word] || 1;return countMap}, {});
편집 (6/12/2015) : 내부에서 설명. countMap은 단어를 빈도와 매핑하는 맵으로, 익명 함수를 볼 수 있습니다. 축소하는 것은 모든 배열 요소와 countMap이 마지막 함수 호출의 반환 값으로 전달되는 인수와 함께 함수를 적용하는 것입니다. 마지막 매개 변수 ({})는 첫 번째 함수 호출에 대한 countMap의 기본값입니다.
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 }
다른 유형의 요소를 구별하는 데 도움이되는 일반 객체 대신 맵 또는 모든 계산은 문자열을 기반으로합니다.
밑줄을 사용하는 경우 기능 경로를 사용할 수 있습니다
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/
을 바탕으로 답 의 @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},{})
));
다음과 같이 배열 프로토 타입을 확장 할 수 있습니다.
Array.prototype.frequencies = function() {
var l = this.length, result = {all:[]};
while (l--){
result[this[l]] = result[this[l]] ? ++result[this[l]] : 1;
}
// all pairs (label, frequencies) to an array of arrays(2)
for (var l in result){
if (result.hasOwnProperty(l) && l !== 'all'){
result.all.push([ l,result[l] ]);
}
}
return result;
};
var freqs = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4].frequencies();
alert(freqs[2]); //=> 5
// or
var freqs = '1,1,2,one,one,2,2,22,three,four,five,three,three,five'
.split(',')
.frequencies();
alert(freqs.three); //=> 3
또는 다음을 활용할 수 있습니다 Array.map
.
Array.prototype.frequencies = function () {
var freqs = {sum: 0};
this.map( function (a){
if (!(a in this)) { this[a] = 1; }
else { this[a] += 1; }
this.sum += 1;
return a; }, freqs
);
return freqs;
}
눈에는 가볍고 쉬운 것이 있습니다 ...
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;
}
최신 자바 스크립트 기능을 사용하여 수행하는 방법은 다음과 같습니다.
먼저 배열을 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)
한 줄 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()])
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];
축소 (고정) 기능이있는 ES6 솔루션 :
const arr = [2, 2, 2, 3, 2]
const count = arr.reduce((pre, cur) => (cur === 2) ? ++pre : pre, 0)
console.log(count) // 4
람다가있는 내 솔루션 :
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)
아래 코드를 확인하십시오.
<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>
이 시도:
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;
}
가장 간단한 해결책은 다음과 같습니다.
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]
이 질문은 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;
나는 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;
}
우리가 이것을 사용하여 훨씬 더 쉽고 쉬운 방법이 있습니다 ramda.js
. 여기 코드 샘플
const ary = [5, 5, 5, 2, 2, 2, 2, 2, 9, 4]; R.countBy(r=> r)(ary)
countBy 문서는 문서에 있습니다
@Emissary에게 자신의 솔루션 조정에 대해 묻는 나의 의견과 관련하여. 내가 처리 한 방식을 추가하는 메신저 :
let distinctArr = yourArray.filter((curElement, index, array) => array.findIndex(t => t.prop1=== curElement.prop1 && t.prop2 === curElement.prop2 && t.prop3=== curElement.prop3) === index);
let distinctWithCount = [...new Set(distinctArr)].map(function(element){element.prop4 = yourArray.filter(t => t.prop1=== element.prop1 && t.prop2 === element.prop2 && t.prop2=== element.prop2).length;
여기서 내가하고있는 일은 먼저 복제본을 제거하고 배열 (distinctArr)을 저장 한 다음 객체가 복제 된 시간을 원래 배열 (yourArray)로 계산하고 발생 값으로 4 번째 속성을 추가하는 것입니다
이 특정 솔루션이 필요한 누군가에게 도움이되기를 바랍니다.
다음은 객체 배열 내에서 발생 횟수를 계산하는 방법입니다. 또한 첫 번째 배열의 내용을 새 배열 안에 배치하여 원래 배열의 순서가 중단되지 않도록 값을 정렬합니다. 그런 다음 재귀 함수를 사용하여 각 요소를 살펴보고 배열 내 각 개체의 수량 속성을 계산합니다.
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)));
}
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]};
}
}, {})
}
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)
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]);
}
참고 URL : https://stackoverflow.com/questions/5667888/counting-the-occurrences-frequency-of-array-elements
'IT story' 카테고리의 다른 글
iOS를 사용하여 텍스트를 클립 보드에 복사 (0) | 2020.05.13 |
---|---|
위도와 경도에서 완전한 주소를 얻는 방법? (0) | 2020.05.13 |
숫자에서 월 이름 가져 오기 (0) | 2020.05.13 |
SSH 키 : " 'id_rsa.pub'에 대한 권한 0644가 너무 열려 있습니다." (0) | 2020.05.13 |
Rails activerecord의 모델에서 속성의 기본값을 어떻게 생성합니까? (0) | 2020.05.13 |