var store = ['1','2','2','3','4'];
voglio scoprire che 2
appaiono come i più nella matrice. Come faccio a farlo?ottenere l'articolo che appare il più delle volte in un array
var store = ['1','2','2','3','4'];
voglio scoprire che 2
appaiono come i più nella matrice. Come faccio a farlo?ottenere l'articolo che appare il più delle volte in un array
vorrei fare qualcosa di simile:
var store = ['1','2','2','3','4'];
var frequency = {}; // array of frequency.
var max = 0; // holds the max frequency.
var result; // holds the max frequency element.
for(var v in store) {
frequency[store[v]]=(frequency[store[v]] || 0)+1; // increment frequency.
if(frequency[store[v]] > max) { // is this frequency > max so far ?
max = frequency[store[v]]; // update max.
result = store[v]; // update result.
}
}
+1 - Molto bello ... Ma vorrei usare un ciclo 'for' per bloccare casi d'angolo in cui l'oggetto array ha proprietà: http://jsfiddle.net/9eJd3/ –
Suggerirei l'aggiunta di' if (store.hasOwnProperty (v)) 'nel caso qualcuno abbia deciso di modificare il prototipo di Object o Array, visto che la gente sembra essere piuttosto entusiasta di farlo qui: P –
@no - Non è abbastanza buono, dato che' store' può avere il suo possedere proprietà che ** non sono ** valori dell'array. (http://jsfiddle.net/vR5JK/). Un ciclo 'for' farà comunque il trucco, dal momento che qualsiasi cosa al di fuori dei valori nell'array non è inclusa in' store [0] 'per' store [store.length] ' –
Fare un istogramma, trovare la chiave per il numero massimo nell'istogramma.
var hist = [];
for (var i = 0; i < store.length; i++) {
var n = store[i];
if (hist[n] === undefined) hist[n] = 0;
else hist[n]++;
}
var best_count = hist[store[0]];
var best = store[0];
for (var i = 0; i < store.length; i++) {
if (hist[store[i]] > best_count) {
best_count = hist[store[i]];
best = store[i];
}
}
alert(best + ' occurs the most at ' + best_count + ' occurrences');
Questo presuppone che non vi siano vincoli o che non ti interessa quale sia selezionato.
Non necessario se l'array è ordinato, però. Quindi può essere un'operazione a passaggio singolo. – Thilo
Come nota a margine, questa è chiamata la modalità della distribuzione. –
Se l'array è ordinato questo dovrebbe funzionare:
function popular(array) {
if (array.length == 0) return [null, 0];
var n = max = 1, maxNum = array[0], pv, cv;
for(var i = 0; i < array.length; i++, pv = array[i-1], cv = array[i]) {
if (pv == cv) {
if (++n >= max) {
max = n; maxNum = cv;
}
} else n = 1;
}
return [maxNum, max];
};
popular([1,2,2,3,4,9,9,9,9,1,1])
[9, 4]
popular([1,2,2,3,4,9,9,9,9,1,1,10,10,10,10,10])
[10, 5]
I valori non devono essere ordinati, solo raggruppati. Un minor numero di confronti si verifica se la frequenza corrente di _mode candidate_ è selezionata 'if (pv! = Cv)'. – greybeard
@greybeard, arr.ort() fa "raggruppare" bene? So che non è adatto a tipi diversi, ma raggruppa correttamente? – user2734550
Questa versione si chiuderà guardando quando il conteggio supera il numero di elementi non ancora conteggiati.
Funziona senza ordinare l'array.
Array.prototype.most= function(){
var L= this.length, freq= [], unique= [],
tem, max= 1, index, count;
while(L>= max){
tem= this[--L];
if(unique.indexOf(tem)== -1){
unique.push(tem);
index= -1, count= 0;
while((index= this.indexOf(tem, index+1))!= -1){
++count;
}
if(count> max){
freq= [tem];
max= count;
}
else if(count== max) freq.push(tem);
}
}
return [freq, max];
}
//test
var A= ["apples","oranges","oranges","oranges","bananas",
"bananas","oranges","bananas"];
alert(A.most()) // [oranges,4]
A.push("bananas");
alert(A.most()) // [bananas,oranges,4]
Se l'array contiene stringhe provare questa soluzione
function GetMaxFrequency (array) {
var store = array;
var frequency = []; // array of frequency.
var result; // holds the max frequency element.
for(var v in store) {
var target = store[v];
var numOccurences = $.grep(store, function (elem) {
return elem === target;
}).length;
frequency.push(numOccurences);
}
maxValue = Math.max.apply(this, frequency);
result = store[$.inArray(maxValue,frequency)];
return result;
}
var store = ['ff','cc','cc','ff','ff','ff','ff','ff','ff','yahya','yahya','cc','yahya'];
alert(GetMaxFrequency(store));
ho risolto in questo modo per reperire il numero intero più comune
function mostCommon(arr) {
// finds the first most common integer, doesn't account for 2 equally common integers (a tie)
freq = [];
// set all frequency counts to 0
for(i = 0; i < arr[arr.length-1]; i++) {
freq[i] = 0;
}
// use index in freq to represent the number, and the value at the index represent the frequency count
for(i = 0; i < arr.length; i++) {
freq[arr[i]]++;
}
// find biggest number's index, that's the most frequent integer
mostCommon = freq[0];
for(i = 0; i < freq.length; i++) {
if(freq[i] > mostCommon) {
mostCommon = i;
}
}
return mostCommon;
}
arr.sort();
var max=0,result,freq = 0;
for(var i=0; i < arr.length; i++){
if(arr[i]===arr[i+1]){
freq++;
}
else {
freq=0;
}
if(freq>max){
result = arr[i];
max = freq;
}
}
return result;
Poiché ci sono molte altre risposte, potrebbe essere utile aggiungere una spiegazione sul motivo per cui la soluzione è preferibile. È possibile aggiungere una spiegazione facendo clic sul pulsante "modifica" ... –
Arr.sort() ordina sempre correttamente un gruppo di tipi diversi nell'array? – user2734550
si @ user2734550. arr.sort() è in grado di ordinare correttamente un gruppo di tipi diversi nell'array. ma se hai a che fare con singoli insieme con numeri a più cifre, potresti dover ordinare in questo modo: arr.sort (funzione (a, b) {return a- b;}) – Ashikodi
Soluzione con enfasi Array.prototype.forEach
e la problema di ottenere più di una chiave se il numero massimo è condiviso tra più elementi.
Modifica: proposta con un ciclo, solo.
var store = ['1', '2', '2', '3', '4', '5', '5'],
distribution = {},
max = 0,
result = [];
store.forEach(function (a) {
distribution[a] = (distribution[a] || 0) + 1;
if (distribution[a] > max) {
max = distribution[a];
result = [a];
return;
}
if (distribution[a] === max) {
result.push(a);
}
});
console.log('max: ' + max);
console.log('key/s with max count: ' + JSON.stringify(result));
console.log(distribution);
Una soluzione piuttosto breve.
function mostCommon(list) {
var keyCounts = {};
var topCount = 0;
var topKey = {};
list.forEach(function(item, val) {
keyCounts[item] = keyCounts[item] + 1 || 1;
if (keyCounts[item] > topCount) {
topKey = item;
topCount = keyCounts[item];
}
});
return topKey;
}
document.write(mostCommon(['AA', 'AA', 'AB', 'AC']))
Questa è la mia soluzione.
var max_frequent_elements = function(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];
}
var max = b[0]
for(var p=1;p<b.length;p++){
if(b[p]>max)max=b[p]
}
var indices = []
for(var q=0;q<a.length;q++){
if(b[q]==max){indices.push(a[q])}
}
return indices;
};
Questa soluzione restituisce un array di numeri più che compaiono in un array, nel caso in cui più numeri appaiono ai tempi "MAX".
function mode(numbers) {
var counterObj = {};
var max = 0;
var result = [];
for(let num in numbers) {
counterObj[numbers[num]] = (counterObj[numbers[num]] || 0) + 1;
if(counterObj[numbers[num]] >= max) {
max = counterObj[numbers[num]];
}
}
for (let num in counterObj) {
if(counterObj[num] == max) {
result.push(parseInt(num));
}
}
return result;
}
Tutte le soluzioni sopra sono iterative.
Ecco un funzionale versione mutazione-meno ES6:
Array.prototype.mostRepresented = function() {
const indexedElements = this.reduce((result, element) => {
return result.map(el => {
return {
value: el.value,
count: el.count + (el.value === element ? 1 : 0),
};
}).concat(result.some(el => el.value === element) ? [] : {value: element, count: 1});
}, []);
return (indexedElements.slice(1).reduce(
(result, indexedElement) => (indexedElement.count > result.count ? indexedElement : result),
indexedElements[0]) || {}).value;
};
Potrebbe essere ottimizzato in particolari situazioni in cui le prestazioni è il collo di bottiglia, ma ha un grande vantaggio di lavorare con qualsiasi tipo di elementi dell'array.
L'ultima riga potrebbe essere sostituito con:
return (indexedElements.maxBy(el => el.count) || {}).value;
Con:
Array.prototype.maxBy = function(fn) {
return this.slice(1).reduce((result, element) => (fn(element) > fn(result) ? element : result), this[0]);
};
per chiarezza
è tale matrice sempre ordinato (come è nel tuo esempio)? – Thilo
Vedi qui per la mia risposta pseudo-codice: http://stackoverflow.com/questions/3774757/c-get-mode-from-list-of-integers/3774791#3774791 – paxdiablo
Se la risposta alla domanda di @ Thilo è sì, gli stessi elementi saranno sempre raggruppati insieme. Ciò ti consente di scorrere l'elenco una volta confrontato ogni elemento con il precedente e di tenere conto di quanti stessi elementi hai incontrato e della corsa più alta incontrata lungo il percorso. Alla fine del ciclo, avrai la tua risposta. Questo verrà eseguito in tempo lineare. Se la risposta alla domanda di @ Thilo è no, quindi ordina prima la lista, seguita dalla strategia sopra. – Asaph