2010-09-23 10 views
20

Sto imparando il codice JavaScript usando W3C e non ho trovato risposta a questa domanda.JavaScript: ottieni l'elemento dell'array che soddisfa una condizione

Sto tentando di eseguire alcune manipolazioni sugli elementi dell'array che soddisfano alcune condizioni.

C'è un modo per farlo se non eseguire gli elementi di matrice in ciclo for? Forse qualcosa di simile (in altre lingue):

foreach (object t in tArray) 
    if (t follows some condition...) t++; 

un'altra cosa, a volte voglio usare il valore dell'elemento e, a volte voglio usare come riferimento. qual è la differenza sintattica?

Inoltre, sarò felice per le raccomandazioni su siti più estesi per l'apprendimento di JavaScript da. grazie

+0

Per imparare Javascript, provare: [Mozilla Developer Center] (https://developer.mozilla.org/en/JavaScript) e il [Web Standards Curriculum] (http://dev.opera.com/articles/view/programming-the-real-basics/) –

risposta

19

Nella maggior parte dei browser (IE non < = 8) array hanno un metodo filter, che non fa proprio quello che si vuole, ma non si crea un array di elementi dell'array originale che soddisfano una determinata condizione:

function isGreaterThanFive(x) { 
    return x > 5; 
} 

[1, 10, 4, 6].filter(isGreaterThanFive); // Returns [10, 6] 

Mozilla Developer Network ha molte buone risorse JavaScript.

+1

Volevo solo aggiungere che è stato aggiunto a IE dalla versione 9 in poi. –

+0

@MiikaL. Buon punto, grazie. Ho aggiornato la mia risposta. –

2

È possibile utilizzare for ... in in JavaScript:

for (var key in array) { 
    if (/* some condition */) { 
     // ... 
    } 
} 

Come di JavaScript 1.6, è possibile utilizzare anche questo:

for each (var element in array) { 
    // ... 
} 

Queste sono destinate principalmente per attraversare le proprietà degli oggetti. Dovresti considerare di usare semplicemente il tuo for -loop.

MODIFICA: È possibile utilizzare un framework JavaScript come jQuery per eliminare questi problemi tra browser. Provaci. Il suo $.each()-method fa il lavoro.

+0

È vero, questi metodi funzionano, ma sono spesso raccomandati contro. Il motivo è che enumera anche altre proprietà dell'oggetto array (e molte librerie aggiungono tali proprietà) che produrranno risultati imprevedibili. – sje397

+0

@ sje397: Giusto. Consiglio vivamente jQuery per questo. Il suo ['$ .each()' -method] (http://api.jquery.com/jQuery.each/) funziona davvero bene e fornisce chiusure. Poiché JavaScript ha scope di funzionalità, questo può essere davvero utile quando si fanno molte cose nei propri loop. – jwueller

+0

L'insieme effettivo di proprietà enumerate da 'for ... in' è del tutto prevedibile, sebbene vari nei vari browser. Ciò che non è generalmente prevedibile è l'ordine di iterazione. Per iterare su un array, 'for ... in' è generalmente una cattiva idea. –

1

Informazioni sugli array

Che di solito si desidera per iterare su array è il metodo forEach:

arr.forEach(function(el) { 
    alert(el); 
}); 

Nel tuo caso specifico per incrementare ogni elemento di array, io consiglierei il metodo map :

arr = arr.map(function(t){ return t+1; }); 

Ci sono anche filter, reduce e altri, anch'essi utili.

Ma come Tim Down già menzionato, questi non funzioneranno di default in IE. Ma puoi anche aggiungere facilmente questi metodi per IE, come mostrato nella documentazione MDC, o addirittura puoi scrivere anche versioni più semplici di quelle nella documentazione MDC (non so perché siano così poco-JavaScript-y laggiù):

if (!Array.prototype.forEach) { 
    Array.prototype.forEach = function(func, scope) { 
    for (var i = 0, len = this.length; i < len; i++) { 
     func.call(scope, this[i], i, this); 
    } 
    }; 
} 

ma non usare il costrutto for ... in per gli array - questo è destinato per gli oggetti.

Chi riferimenti

un'altra cosa, a volte voglio usare il valore dell'elemento e, a volte voglio usare come riferimento. Qual è la differenza sintattica?

In JavaScript ogni variabile è in effetti un riferimento a qualche oggetto. Ma quei riferimenti sono passati per valore. Mi spiego ...

È possibile passare un oggetto a una funzione che modifica l'oggetto e le modifiche saranno visto fuori della funzione:

function incrementHeight(person) { 
    person.height = person.height + 1; 
} 
var p = {height: 10); 
alert(p.height); // outputs: 10 
incrementHeight(p); 
alert(p.height); // outputs: 11 

Qui si modifica il valore a cui i punti di riferimento person per e così il cambiamento sarà riflesso al di fuori della funzione.

Ma qualcosa di simile fallisce:

function incrementHeight(height) { 
    height = height + 1; 
} 
var h = 10; 
alert(h); // outputs: 10 
incrementHeight(h); 
alert(h); // outputs: 10 

Qui si crea un oggetto completamente nuovo 11 e assegnare il suo riferimento alla variabile height. Ma la variabile h al di fuori della funzione contiene ancora il vecchio riferimento e quindi rimane da puntare a 10.

0

Appena incontrato lo stesso problema. Tim Down venuto vicino, ha solo bisogno di un wrapper per la lunghezza della matrice filtrato:

// count elements fulfilling a condition 
Array.prototype.count = function (f) { 
    return this.filter(f).length; 
}; 

Usage:

// get the answer weight from the question's values array 
var w = Math.pow(q.values.count(function(v) { return v !== -1; }), -1); 

Spero che le risposte a questa domanda di vecchia data!

2

Qui un breve modo per scrivere un filtro. Da una matrice di numeri che restituisce tutti i valori maggiori di 5.

myArray.filter((x) => { return x > 5; }) 

Esempio di utilizzo:

var filterResult = [1, 10, 4, 6].filter((x) => { return x > 5; }); 
console.log(filterResult); // returns [ 10, 6 ] 

E qui un filtro per un array di oggetti , che controlla un struttura condizione .

myArray.filter((x) => { return x.myNumber > 5; }) 

Esempio di utilizzo:

var myArray = [{myNumber: 1, name: 'one'}, {myNumber: 3, name: 'tree'}, {myNumber: 6, name: 'six'}, {myNumber: 8, name: 'eight'}]; 
var result = myArray.filter((x) => { return x.myNumber > 5; }); 
console.log(result); // returns [ { myNumber: 6, name: 'six' }, { myNumber: 8, name: 'eight' } ] 
Problemi correlati