it-swarm.com.de

Finden Sie idiomatisch die Anzahl der Vorkommen, die ein bestimmter Wert in einem Array hat

Ich habe ein Array mit sich wiederholenden Werten. Ich möchte die Anzahl der Vorkommen für einen bestimmten Wert ermitteln. 

Wenn ich beispielsweise ein Array so definiert habe: var dataset = [2,2,4,2,6,4,7,8];, möchte ich die Anzahl der Vorkommen eines bestimmten Werts im Array ermitteln. Das Programm sollte also zeigen, dass bei drei Vorkommen des Wertes 2 ein Vorkommen des Wertes 6 usw. auftritt.

Was ist der idiomatischste/eleganteste Weg, dies zu tun?

35
Shrey Gupta

reduce ist hier geeigneter als filter, da sie kein temporäres Array nur zum Zählen aufbaut.

var dataset = [2,2,4,2,6,4,7,8];
var search = 2;

var count = dataset.reduce(function(n, val) {
    return n + (val === search);
}, 0);

console.log(count);

Beachten Sie, dass es einfach ist, das zu erweitern, um ein benutzerdefiniertes übereinstimmendes Prädikat zu verwenden, beispielsweise um Objekte mit einer bestimmten Eigenschaft zu zählen:

people = [
    {name: 'Mary', gender: 'girl'},
    {name: 'Paul', gender: 'boy'},
    {name: 'John', gender: 'boy'},
    {name: 'Lisa', gender: 'girl'},
    {name: 'Bill', gender: 'boy'},
    {name: 'Maklatura', gender: 'girl'}
]

var numBoys = people.reduce(function (n, person) {
    return n + (person.gender == 'boy');
}, 0);

console.log(numBoys);

Das Zählen aller Elemente, dh das Erstellen eines Objekts wie {x:count of xs} ist in Javascript kompliziert, da Objektschlüssel nur Zeichenfolgen sein können, sodass Sie ein Array mit gemischten Typen nicht zuverlässig zählen können. Die folgende einfache Lösung funktioniert jedoch in den meisten Fällen gut:

count = function (ary, classifier) {
    classifier = classifier || String;
    return ary.reduce(function (counter, item) {
        var p = classifier(item);
        counter[p] = counter.hasOwnProperty(p) ? counter[p] + 1 : 1;
        return counter;
    }, {})
};

people = [
    {name: 'Mary', gender: 'girl'},
    {name: 'Paul', gender: 'boy'},
    {name: 'John', gender: 'boy'},
    {name: 'Lisa', gender: 'girl'},
    {name: 'Bill', gender: 'boy'},
    {name: 'Maklatura', gender: 'girl'}
];

// If you don't provide a `classifier` this simply counts different elements:

cc = count([1, 2, 2, 2, 3, 1]);
console.log(cc);

// With a `classifier` you can group elements by specific property:

countByGender = count(people, function (item) {
    return item.gender
});
console.log(countByGender);

2017 Update

In ES6 verwenden Sie das Objekt Map, um Objekte beliebigen Typs zuverlässig zu zählen:

class Counter extends Map {
    constructor(iter, key=null) {
        super();
        this.key = key || (x => x);
        for (let x of iter) {
            this.add(x);
        }
    }
    add(x) {
      x = this.key(x);
      this.set(x, (this.get(x) || 0) + 1);
    }
}

// again, with no classifier just count distinct elements

results = new Counter([1, 2, 3, 1, 2, 3, 1, 2, 2]);
for (let [number, times] of results.entries())
    console.log('%s occurs %s times', number, times);


// counting objects

people = [
    {name: 'Mary', gender: 'girl'},
    {name: 'John', gender: 'boy'},
    {name: 'Lisa', gender: 'girl'},
    {name: 'Bill', gender: 'boy'},
    {name: 'Maklatura', gender: 'girl'}
];


chessChampions = {
    2010: people[0],
    2012: people[0],
    2013: people[2],
    2014: people[0],
    2015: people[2],
};

results = new Counter(Object.values(chessChampions));
for (let [person, times] of results.entries())
    console.log('%s won %s times', person.name, times);

// you can also provide a classifier as in the above

byGender = new Counter(people, x => x.gender);
for (let g of ['boy', 'girl'])
   console.log("there are %s %ss", byGender.get(g), g);

74
georg

Neuere Browser nur wegen der Verwendung von Array.filter

var dataset = [2,2,4,2,6,4,7,8];
var search = 2;
var occurrences = dataset.filter(function(val) {
    return val === search;
}).length;
console.log(occurrences); // 3
11
goat
array.filter(c => c === searchvalue).length;
9
Julian Wagner

Hier ist eine Möglichkeit,ALLEauf einmal anzuzeigen:

var dataset = [2, 2, 4, 2, 6, 4, 7, 8];
var counts = {}, i, value;
for (i = 0; i < dataset.length; i++) {
    value = dataset[i];
    if (typeof counts[value] === "undefined") {
        counts[value] = 1;
    } else {
        counts[value]++;
    }
}
console.log(counts);
// Object {
//    2: 3,
//    4: 2,
//    6: 1,
//    7: 1,
//    8: 1
//}
8
Salman A

Mit einer normalen Schleife können Sie die Vorkommen konsistent und zuverlässig finden:

const dataset = [2,2,4,2,6,4,7,8];

function getNumMatches(array, valToFind) {
    let numMatches = 0;
    for (let i = 0, j = array.length; i < j; i += 1) {
        if (array[i] === valToFind) {
            numMatches += 1;
        }
    }
    return numMatches;
}

alert(getNumMatches(dataset, 2)); // should alert 3

DEMO:https://jsfiddle.net/a7q9k4uu/

Um es allgemeiner zu machen, könnte die Funktion eine Prädikatsfunktion mit benutzerdefinierter Logik akzeptieren (truefalse), die die endgültige Anzahl bestimmt. Zum Beispiel:

const dataset = [2,2,4,2,6,4,7,8];

function getNumMatches(array, predicate) {
    let numMatches = 0;
    for (let i = 0, j = array.length; i < j; i += 1) {
        const current = array[i];
        if (predicate(current) === true) {
            numMatches += 1;
        }
    }
    return numMatches;
}

const numFound = getNumMatches(dataset, (item) => {
    return item === 2;
});

alert(numFound); // should alert 3

_/DEMO:https://jsfiddle.net/57en9nar/1/

6
Ian
var dataset = [2,2,4,2,6,4,7,8], count = {}

dataset.forEach(function(el){
    count[el] = count[el] + 1 || 1
});

console.log(count)

//  {
//    2: 3,
//    4: 2,
//    6: 1,
//    7: 1,
//    8: 1
//  }
5
Manolis

Sie können die array.reduce(callback[, initialValue])-Methode in JavaScript 1.8 verwenden. 

var dataset = [2,2,4,2,6,4,7,8],
    dataWithCount = dataset.reduce( function( o , v ) {

        if ( ! o[ v ] ) {
            o[ v ] = 1 ;  
        }  else {
            o[ v ] = o[ v ] + 1;
        }      

        return o ;    

    }, {} );

// print data with count.
for( var i in  dataWithCount ){
     console.log( i + 'occured ' + dataWithCount[i] + 'times ' ); 
}

// find one number
var search = 2,
    count = dataWithCount[ search ] || 0;
3
rab

Sie können alle Elemente in einem Array in einer einzigen Zeile zählen, indem Sie verkleinern. 

[].reduce((a,b) => (a[b] = a[b] + 1 || 1) && a, {})

Dies ergibt ein Objekt, dessen Schlüssel die verschiedenen Elemente im Array sind, und die Werte die Anzahl der Vorkommen von Elementen im Array. Sie können dann auf eine oder mehrere der Zählungen zugreifen, indem Sie auf einen entsprechenden Schlüssel des Objekts zugreifen.

Zum Beispiel, wenn Sie das Obige in eine Funktion namens count() einschließen würden:

function count(arr) {
  return arr.reduce((a,b) => (a[b] = a[b] + 1 || 1) && a, {})
}

count(['example'])          // { example: 1 }
count([2,2,4,2,6,4,7,8])[2] // 3
2
justin.m.chase

Ich fand es sinnvoller, eine Liste von Objekten mit einem Schlüssel für das, was gezählt wird, und einem Schlüssel für die Zählung zu erhalten:

const data = [2,2,4,2,6,4,7,8]
let counted = []
for (var c of data) {
  const alreadyCounted = counted.map(c => c.name)
  if (alreadyCounted.includes(c)) {
    counted[alreadyCounted.indexOf(c)].count += 1
  } else {
    counted.Push({ 'name': c, 'count': 1})
  }
}
console.log(counted)

was gibt zurück: 

[ { name: 2, count: 3 },
  { name: 4, count: 2 },
  { name: 6, count: 1 },
  { name: 7, count: 1 },
  { name: 8, count: 1 } ]

Es ist nicht die sauberste Methode, und wenn jemand weiß, wie man mit reduce dasselbe Ergebnis erzielt, lass es mich wissen. Es führt jedoch zu einem Ergebnis, mit dem man relativ leicht arbeiten kann.

0

Erstens können Sie mit Brute Force Solution arbeiten, indem Sie mit der linearen Suche fortfahren.

public int LinearSearchcount(int[] A, int data){
  int count=0;
  for(int i=0;i<A.length;i++) {
    if(A[i]==data) count++;
  }
  return count;
}

Um dies zu bewerkstelligen, erhalten wir die Zeitkomplexität als O (n). Aber durch die binäre Suche können wir unsere Komplexität verbessern.

0
Balaji Mj