Come ottenere valori distinti da una matrice di oggetti in JavaScript?


385

Supponendo che ho il seguente:

var array = 
    [
        {"name":"Joe", "age":17}, 
        {"name":"Bob", "age":17}, 
        {"name":"Carl", "age": 35}
    ]

Qual è il modo migliore per essere in grado di ottenere una matrice di tutte le età distinte in modo tale da ottenere una matrice di risultati di:

[17, 35]

C'è un modo in cui potrei in alternativa strutturare i dati o un metodo migliore in modo tale da non dover scorrere attraverso ciascun array verificando il valore di "age" e verificando l'esistenza di un altro array e aggiungendolo se no?

Se ci fosse un modo, potrei semplicemente tirare fuori le epoche distinte senza iterare ...

Il modo inefficace attuale vorrei migliorare ... Se ciò significa che invece di "array" sia un array di oggetti, ma una "mappa" di oggetti con una chiave univoca (ovvero "1,2,3") che sarebbe va bene lo stesso. Sto solo cercando il modo più efficiente in termini di prestazioni.

Quello che segue è come lo faccio attualmente, ma per me, l'iterazione sembra essere scadente per l'efficienza anche se funziona ...

var distinct = []
for (var i = 0; i < array.length; i++)
   if (array[i].age not in distinct)
      distinct.push(array[i].age)

34
l'iterazione non è "scadente per l'efficienza" e non puoi fare nulla per ogni elemento "senza iterare". puoi usare vari metodi dall'aspetto funzionale, ma alla fine qualcosa su un certo livello deve scorrere gli elementi.
Eevee,

// 100% di codice di esecuzione const listOfTags = [{id: 1, etichetta: "Hello", colore: "rosso", ordinamento: 0}, {id: 2, etichetta: "World", colore: "verde", ordinamento : 1}, {id: 3, etichetta: "Hello", colore: "blu", ordinamento: 4}, {id: 4, etichetta: "Sunshine", colore: "giallo", ordinamento: 5}, {id : 5, etichetta: "Ciao", colore: "rosso", ordinamento: 6}], keys = ['label', 'color'], filtered = listOfTags.filter ((s => o => (k => ! s.has (k) && s.add (k)) (keys.map (k => o [k]). join ('|'))) (nuovo set)); console.log (filtrato);
Sandeep Mishra

1
la generosità è ottima, ma alla domanda con i dati e la risposta forniti è già stata data una risposta qui: stackoverflow.com/questions/53542882/… . qual è lo scopo della taglia? dovrei rispondere a questo particolare problema con due o più chiavi?
Nina Scholz,

Setoggetto e mapsono dispendiosi. Questo lavoro richiede solo una .reduce()fase semplice .
Redu,

Risposte:


127

Se questo fosse PHP, creerei un array con le chiavi e lo prenderei array_keysalla fine, ma JS non ha tale lusso. Invece, prova questo:

var flags = [], output = [], l = array.length, i;
for( i=0; i<l; i++) {
    if( flags[array[i].age]) continue;
    flags[array[i].age] = true;
    output.push(array[i].age);
}

15
No, perché array_uniqueconfronterebbe l'intero articolo, non solo l'età richiesta qui.
Niet the Dark Absol,

6
Penso che flags = {}sia meglio diflags = []
zhuguowei il

3
@zhuguowei forse, anche se non c'è nulla di veramente sbagliato negli array sparsi - e ho anche supposto che agesia un numero intero relativamente piccolo (<120 sicuramente)
Niet the Dark Absol

come possiamo anche stampare il numero totale di persone che hanno la stessa età?
user1788736

607

Se si utilizza ES6 / ES2015 o versione successiva, è possibile farlo in questo modo:

const unique = [...new Set(array.map(item => item.age))];

Ecco un esempio su come farlo.


11
Ottengo un errore:TypeError: (intermediate value).slice is not a function
AngJobs su Github il

7
@ Thomas ... significa operatore di diffusione. In questo caso significa creare un nuovo set e diffonderlo in un elenco. Puoi trovare ulteriori informazioni qui: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Vlad Bezden,

10
per dattiloscritto devi usare il nuovo set racchiuso in Array.from () ... fornirò la seguente risposta. @AngJobs
Christian Matthew,

4
è possibile scoprire oggetti unici basati su più chiavi nell'oggetto?
Jefree Sujit,

14
Questa soluzione è stata data quasi alla lettera pochi mesi prima da @Russell Vea. Hai controllato le risposte esistenti? Ma ancora una volta, 266+ voti mostrano che nessun altro ha controllato.
Dan Dascalescu,

165

usando ES6

let array = [
  { "name": "Joe", "age": 17 },
  { "name": "Bob", "age": 17 },
  { "name": "Carl", "age": 35 }
];
array.map(item => item.age)
  .filter((value, index, self) => self.indexOf(value) === index)

> [17, 35]

2
Se voglio ottenere il valore con il suo indice, allora come posso ottenere Esempio: Voglio ottenere {"name": "Bob", "age": "17"}, {"name": "Bob", "age ":" 17 "}
Abdullah Al Mamun,

10
Ecco perché devi continuare a scorrere
Alejandro Bastidas,

5
@AbdullahAlMamun puoi usare map in .filter invece di chiamare prima .map, in questo modo:array.filter((value, index, self) => self.map(x => x.age).indexOf(value.age) == index)
Leo

1
ps: .map all'interno di .filter può essere lenta, quindi fai attenzione con array di grandi dimensioni
Leone

2
@IvanNosov il tuo frammento è molto buono anche se diverse linee di spiegazione su come funziona con i puntatori per mappare e filtrare la documentazione lo renderanno perfetto e chiaro per i principianti
azakgaim

128

È possibile utilizzare un approccio dizionario come questo. Fondamentalmente si assegna il valore che si desidera sia distinto come chiave nel "dizionario" (qui si usa un array come oggetto per evitare la modalità dizionario). Se la chiave non esisteva, aggiungi quel valore come distinto.

Ecco una demo funzionante:

var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
var unique = [];
var distinct = [];
for( let i = 0; i < array.length; i++ ){
  if( !unique[array[i].age]){
    distinct.push(array[i].age);
    unique[array[i].age] = 1;
  }
}
var d = document.getElementById("d");
d.innerHTML = "" + distinct;
<div id="d"></div>

Questo sarà O (n) dove n è il numero di oggetti nella matrice e m è il numero di valori univoci. Non esiste un modo più veloce di O (n) perché è necessario ispezionare ogni valore almeno una volta.

La versione precedente di questo utilizzava un oggetto, e per in. Questi erano di natura minore e da allora sono stati leggermente aggiornati sopra. Tuttavia, il motivo di un apparente progresso nelle prestazioni tra le due versioni nel jsperf originale era dovuto al fatto che le dimensioni del campione di dati erano così ridotte. Pertanto, il confronto principale nella versione precedente stava esaminando la differenza tra la mappa interna e l'uso del filtro rispetto alle ricerche in modalità dizionario.

Ho aggiornato il codice sopra, come notato, tuttavia, ho anche aggiornato jsperf per guardare attraverso 1000 oggetti invece di 3. 3 trascurato molte delle insidie ​​prestazionali coinvolte ( jsperf obsoleto ).

Prestazione

https://jsperf.com/filter-vs-dictionary-more-data Quando ho eseguito questo dizionario è stato del 96% più veloce.

filtro vs dizionario


4
veloce e senza ulteriori plug-in richiesti. Davvero fantastico
mihai il

2
che ne diciif( typeof(unique[array[i].age]) == "undefined"){ distinct.push(array[i].age); unique[array[i].age] = 0; }
Senza tempo

7
Wow, le prestazioni sono davvero cambiate a favore dell'opzione map. Fai clic sul link jsperf!
AL

1
@ 98percentmonkey - L'oggetto è stato utilizzato per facilitare "l'approccio del dizionario". All'interno dell'oggetto, ogni occorrenza tracciata viene aggiunta come chiave (o bin). In questo modo, quando ci imbattiamo in un'occorrenza, possiamo verificare se esiste la chiave (o bin); se esiste, sappiamo che la ricorrenza non è unica - se non esiste, sappiamo che la ricorrenza è unica e la aggiungiamo.
Travis J

1
@ 98percentmonkey - Il motivo dell'uso di un oggetto è che la ricerca è O (1) poiché controlla una volta il nome di una proprietà, mentre una matrice è O (n) poiché deve controllare ogni valore per verificare l'esistenza. Alla fine del processo, l'insieme di chiavi (bin) nell'oggetto rappresenta l'insieme di occorrenze uniche.
Travis J

91

Ecco come lo risolveresti usando il nuovo Set via ES6 per Typescript dal 25 agosto 2017

Array.from(new Set(yourArray.map((item: any) => item.id)))

3
questo ha aiutato, stava diventando grazie prima. Il tipo 'Set' non è un tipo di array
robert king,

1
Questa è un'ottima risposta Fino a quando non ho fatto scorrere verso il basso fino a questo, stavo per scrivere una risposta dicendo: Object.keys (limits.reduce <any> ((x, y) => {x [y] = null; return x;}, {} )); Ma questa risposta è più concisa e si applica a tutti i tipi di dati anziché solo alle stringhe.
jgosar,

1
questa risposta è spettacolare!
lukeocodes

79

Utilizzando le funzionalità ES6, potresti fare qualcosa del tipo:

const uniqueAges = [...new Set( array.map(obj => obj.age)) ];

6
Questo approccio funzionerà solo su tipi primitivi (come in questo caso poiché le età sono una matrice di numeri) ma non riuscirà per gli oggetti.
k0pernikus,

qualche idea su come farlo funzionare per oggetti con due chiavi?
cegprakash,

1
Qualcosa del genereconst uniqueObjects = [ ...new Set( array.map( obj => obj.age) ) ].map( age=> { return array.find(obj => obj.age === age) } )
Harley B,

62

Vorrei solo mappare e rimuovere i duplicati:

var ages = array.map(function(obj) { return obj.age; });
ages = ages.filter(function(v,i) { return ages.indexOf(v) == i; });

console.log(ages); //=> [17, 35]

Modifica: Aight! Non è il modo più efficiente in termini di prestazioni, ma l'IMO più semplice e leggibile. Se ti interessa davvero la micro-ottimizzazione o hai enormi quantità di dati, un forciclo regolare sarà più "efficiente".


3
@elclanrs - "il modo più efficiente in termini di prestazioni" - Questo approccio è lento .
Travis J,

1
@Eevee: capisco. La versione di sottolineatura nella tua risposta non è neanche molto veloce , voglio dire, alla fine scegli cosa è più conveniente, dubito che l'1-30% in più o in meno rifletta "un enorme miglioramento" nei test generici e quando gli OP / s sono in migliaia .
elclanrs,

4
bene certo. con solo tre elementi , la cosa più veloce è creare tre variabili e usare alcuni ifs. otterrai tre risultati molto diversi con tre milioni.
Eevee,

1
non veloce ma nel mio caso ha fatto il trucco perché non ho a che fare con un set di dati di grandi dimensioni, grazie.
Felipe Alarcon,

37
var unique = array
    .map(p => p.age)
    .filter((age, index, arr) => arr.indexOf(age) == index)
    .sort(); // sorting is optional

// or in ES6

var unique = [...new Set(array.map(p => p.age))];

// or with lodash

var unique = _.uniq(_.map(array, 'age'));

Esempio ES6

const data = [
  { name: "Joe", age: 17}, 
  { name: "Bob", age: 17}, 
  { name: "Carl", age: 35}
];

const arr = data.map(p => p.age); // [17, 17, 35]
const s = new Set(arr); // {17, 35} a set removes duplications, but it's still a set
const unique = [...s]; // [17, 35] Use the spread operator to transform a set into an Array
// or use Array.from to transform a set into an array
const unique2 = Array.from(s); // [17, 35]

6
Mentre questo codice può rispondere alla domanda, fornendo un contesto aggiuntivo riguardo a come e perché risolve il problema migliorerebbe il valore a lungo termine della risposta.
Alexander,

Il primo che utilizza indexOf rispetto all'indice è semplicemente geniale.
ahimè,

Si noti che questo funziona solo per i valori primitivi. Se hai una serie di date, allora hai bisogno di alcuni metodi più personalizzati. Per saperne di più qui: codeburst.io/javascript-array-distinct-5edc93501dc4
Molx

36

Per coloro che vogliono restituire un oggetto con tutte le proprietà uniche per chiave

const array =
  [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
  ]

const key = 'age';

const arrayUniqueByKey = [...new Map(array.map(item =>
  [item[key], item])).values()];

console.log(arrayUniqueByKey);

   /*OUTPUT
       [
        { "name": "Bob", "age": 17 },
        { "name": "Carl", "age": 35 }
       ]
   */

 // Note: this will pick the last duplicated item in the list.


2
Nota: questo selezionerà l'ultimo elemento duplicato nell'elenco.
Eugene Kulabuhov,

1
Aggiungendo questo alla risposta!
Arun Kumar Saini,

1
Esattamente quello che stavo cercando. Grazie mille per averlo condiviso!
Devner

1
Penso che questa dovrebbe essere la risposta migliore per essere onesti!
Jaroslav Benc

26

Esistono già molte risposte valide, ma volevo aggiungerne una che utilizza solo il reduce()metodo perché è pulito e semplice.

function uniqueBy(arr, prop){
  return arr.reduce((a, d) => {
    if (!a.includes(d[prop])) { a.push(d[prop]); }
    return a;
  }, []);
}

Usalo in questo modo:

var array = [
  {"name": "Joe", "age": 17}, 
  {"name": "Bob", "age": 17}, 
  {"name": "Carl", "age": 35}
];

var ages = uniqueBy(array, "age");
console.log(ages); // [17, 35]

20

La forEachversione della risposta di @ travis-j (utile sui browser moderni e sul mondo Node JS):

var unique = {};
var distinct = [];
array.forEach(function (x) {
  if (!unique[x.age]) {
    distinct.push(x.age);
    unique[x.age] = true;
  }
});

34% più veloce su Chrome v29.0.1547: http://jsperf.com/filter-versus-dictionary/3

E una soluzione generica che accetta una funzione mapper (leggermente più lenta della mappa diretta, ma è prevista):

function uniqueBy(arr, fn) {
  var unique = {};
  var distinct = [];
  arr.forEach(function (x) {
    var key = fn(x);
    if (!unique[key]) {
      distinct.push(key);
      unique[key] = true;
    }
  });
  return distinct;
}

// usage
uniqueBy(array, function(x){return x.age;}); // outputs [17, 35]

1
Mi piace di più la soluzione generica poiché è improbabile che l'età sia l'unico valore distinto necessario in uno scenario del mondo reale.
Toft

5
Nel generico, cambia "distinct.push (chiave)" in "distinct.push (x)" per restituire un elenco degli elementi effettivi, che trovo altamente utilizzabili!
Silas Hansen,

15

Ho iniziato ad attaccare Underscore per impostazione predefinita in tutti i nuovi progetti, quindi non devo mai pensare a questi piccoli problemi di munging dei dati.

var array = [{"name":"Joe", "age":17}, {"name":"Bob", "age":17}, {"name":"Carl", "age": 35}];
console.log(_.chain(array).map(function(item) { return item.age }).uniq().value());

Produce [17, 35].


13

Ecco un altro modo per risolvere questo:

var result = {};
for(var i in array) {
    result[array[i].age] = null;
}
result = Object.keys(result);

Non ho idea di quanto sia veloce questa soluzione rispetto alle altre, ma mi piace l'aspetto più pulito. ;-)


EDIT: Ok, quanto sopra sembra essere la soluzione più lenta di tutti qui.

Ho creato un caso di test delle prestazioni qui: http://jsperf.com/distinct-values-from-array

Invece di testare per le età (numeri interi), ho scelto di confrontare i nomi (stringhe).

Il metodo 1 (soluzione di TS) è molto veloce. È interessante notare che il Metodo 7 supera di gran lunga tutte le altre soluzioni, qui mi sono appena liberato di .indexOf () e ne ho usato un'implementazione "manuale", evitando chiamate di funzione in loop:

var result = [];
loop1: for (var i = 0; i < array.length; i++) {
    var name = array[i].name;
    for (var i2 = 0; i2 < result.length; i2++) {
        if (result[i2] == name) {
            continue loop1;
        }
    }
    result.push(name);
}

La differenza nelle prestazioni con Safari e Firefox è sorprendente e sembra che Chrome faccia il miglior lavoro di ottimizzazione.

Non sono esattamente sicuro del perché i frammenti di cui sopra siano così veloci rispetto agli altri, forse qualcuno più saggio di me ha una risposta. ;-)


9

usando lodash

var array = [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
];
_.chain(array).pluck('age').unique().value();
> [17, 35]

2
Puoi spiegare come farlo con javascript semplice come è implicito nella domanda?
Ruskin,

è una funzione di sottolineatura _.chain
vini,

2
ma pluck () non è in lodash.
Yash Vekaria,

1
_.chain (array) .map ( 'età') unico valore () ()..; ha funzionato per me.
Yash Vekaria,

versione 4.0 ha avuto alcune modifiche rottura riferimento - stackoverflow.com/a/31740263/4050261
Adarsh Madrecha

7

Usando Lodash

var array = [
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
];

_.chain(array).map('age').unique().value();

Resi [17,35]


6
function get_unique_values_from_array_object(array,property){
    var unique = {};
    var distinct = [];
    for( var i in array ){
       if( typeof(unique[array[i][property]]) == "undefined"){
          distinct.push(array[i]);
       }
       unique[array[i][property]] = 0;
    }
    return distinct;
}


5

Ecco una soluzione versatile che utilizza la riduzione, consente la mappatura e mantiene l'ordine di inserimento.

articoli : un array

mapper : una funzione unaria che mappa l'elemento ai criteri, oppure vuota per mappare l'elemento stesso.

function distinct(items, mapper) {
    if (!mapper) mapper = (item)=>item;
    return items.map(mapper).reduce((acc, item) => {
        if (acc.indexOf(item) === -1) acc.push(item);
        return acc;
    }, []);
}

uso

const distinctLastNames = distinct(items, (item)=>item.lastName);
const distinctItems = distinct(items);

Puoi aggiungerlo al tuo prototipo di array e tralasciare il parametro items se è il tuo stile ...

const distinctLastNames = items.distinct( (item)=>item.lastName) ) ;
const distinctItems = items.distinct() ;

È inoltre possibile utilizzare un set anziché un array per accelerare la corrispondenza.

function distinct(items, mapper) {
    if (!mapper) mapper = (item)=>item;
    return items.map(mapper).reduce((acc, item) => {
        acc.add(item);
        return acc;
    }, new Set());
}

5

const x = [
  {"id":"93","name":"CVAM_NGP_KW"},
  {"id":"94","name":"CVAM_NGP_PB"},
  {"id":"93","name":"CVAM_NGP_KW"},
  {"id":"94","name":"CVAM_NGP_PB"}
].reduce(
  (accumulator, current) => accumulator.some(x => x.id === current.id)? accumulator: [...accumulator, current ], []
)

console.log(x)

/* output 
[ 
  { id: '93', name: 'CVAM_NGP_KW' },
  { id: '94', name: 'CVAM_NGP_PB' } 
]
*/


2
sembra O (n ^ 2)
cegprakash,

4

Ho appena trovato questo e ho pensato che fosse utile

_.map(_.indexBy(records, '_id'), function(obj){return obj})

Di nuovo usando il trattino basso , quindi se hai un oggetto come questo

var records = [{_id:1,name:'one', _id:2,name:'two', _id:1,name:'one'}]

ti darà solo gli oggetti unici.

Quello che succede qui è che indexByrestituisce una mappa come questa

{ 1:{_id:1,name:'one'}, 2:{_id:2,name:'two'} }

e solo perché è una mappa, tutte le chiavi sono uniche.

Quindi sto solo mappando questo elenco sull'array.

Nel caso in cui siano necessari solo valori distinti

_.map(_.indexBy(records, '_id'), function(obj,key){return key})

Tieni presente che keyviene restituito come stringa, quindi, se hai bisogno di numeri interi, dovresti farlo

_.map(_.indexBy(records, '_id'), function(obj,key){return parseInt(key)})

4

penso che stai cercando la funzione groupBy (usando Lodash)

_personsList = [{"name":"Joe", "age":17}, 
                {"name":"Bob", "age":17}, 
                {"name":"Carl", "age": 35}];
_uniqAgeList = _.groupBy(_personsList,"age");
_uniqAges = Object.keys(_uniqAgeList);

produce risultato:

17,35

Demo jsFiddle: http://jsfiddle.net/4J2SX/201/


3

Se come me preferisci uno più "funzionale" senza compromettere la velocità, questo esempio usa una rapida ricerca nel dizionario racchiusa all'interno per ridurre la chiusura.

var array = 
[
    {"name":"Joe", "age":17}, 
    {"name":"Bob", "age":17}, 
    {"name":"Carl", "age": 35}
]
var uniqueAges = array.reduce((p,c,i,a) => {
    if(!p[0][c.age]) {
        p[1].push(p[0][c.age] = c.age);
    }
    if(i<a.length-1) {
        return p
    } else {
        return p[1]
    }
}, [{},[]])

Secondo questo test la mia soluzione è due volte più veloce della risposta proposta


3
[...new Set([
    { "name": "Joe", "age": 17 },
    { "name": "Bob", "age": 17 },
    { "name": "Carl", "age": 35 }
  ].map(({ age }) => age))]

3

So che il mio codice ha poca lunghezza e poca complessità temporale ma è comprensibile, quindi ho provato in questo modo.

Sto cercando di sviluppare una funzione basata sul prototipo qui e anche il codice cambia.

Qui, Distinct è la mia funzione prototipo.

<script>
  var array = [{
      "name": "Joe",
      "age": 17
    },
    {
      "name": "Bob",
      "age": 17
    },
    {
      "name": "Carl",
      "age": 35
    }
  ]

  Array.prototype.Distinct = () => {
    var output = [];
    for (let i = 0; i < array.length; i++) {
      let flag = true;
      for (let j = 0; j < output.length; j++) {
        if (array[i].age == output[j]) {
          flag = false;
          break;
        }
      }
      if (flag)
        output.push(array[i].age);
    }
    return output;
  }
  //Distinct is my own function
  console.log(array.Distinct());
</script>


2

Se si dispone di Array.prototype.includes o sono disposti a polyfill esso, questo funziona:

var ages = []; array.forEach(function(x) { if (!ages.includes(x.age)) ages.push(x.age); });

1

Il mio codice qui sotto mostrerà l'array univoco di età così come il nuovo array che non ha età duplicata

var data = [
  {"name": "Joe", "age": 17}, 
  {"name": "Bob", "age": 17}, 
  {"name": "Carl", "age": 35}
];

var unique = [];
var tempArr = [];
data.forEach((value, index) => {
    if (unique.indexOf(value.age) === -1) {
        unique.push(value.age);
    } else {
        tempArr.push(index);    
    }
});
tempArr.reverse();
tempArr.forEach(ele => {
    data.splice(ele, 1);
});
console.log('Unique Ages', unique);
console.log('Unique Array', data);```

1

Ho scritto il mio in TypeScript, per un caso generico, come quello in Kotlin Array.distinctBy {}...

function distinctBy<T, U extends string | number>(array: T[], mapFn: (el: T) => U) {
  const uniqueKeys = new Set(array.map(mapFn));
  return array.filter((el) => uniqueKeys.has(mapFn(el)));
}

Dove Uè lavabile, ovviamente. Per gli oggetti, potresti aver bisogno di https://www.npmjs.com/package/es6-json-stable-stringify


1

Nel caso abbiate bisogno di un unico oggetto intero

const _ = require('lodash');

var objects = [
  { 'x': 1, 'y': 2 },
  { 'y': 1, 'x': 2 },
  { 'x': 2, 'y': 1 },
  { 'x': 1, 'y': 2 }
];

_.uniqWith(objects, _.isEqual);

[Oggetto {x: 1, y: 2}, Oggetto {x: 2, y: 1}]


downvoter: mente spiegando perché il downvote?
cegprakash,

1

Rispondere a questa vecchia domanda è piuttosto inutile, ma esiste una risposta semplice che parla della natura di Javascript. Gli oggetti in Javascript sono intrinsecamente tabelle hash. Possiamo usarlo per ottenere un hash di chiavi uniche:

var o = {}; array.map(function(v){ o[v.age] = 1; });

Quindi possiamo ridurre l'hash a una matrice di valori univoci:

var a2 = []; for (k in o){ a2.push(k); }

Questo è tutto ciò di cui hai bisogno. L'array a2 contiene solo le età uniche.


1

One-liner semplice con grandi prestazioni. 6% più veloce rispetto alle soluzioni ES6 nei miei test .

var ages = array.map(function(o){return o.age}).filter(function(v,i,a) {
    return a.indexOf(v)===i
});

@ Jeb50 Vuoi aggiungere una linea multipla di facile lettura? Guardando gli altri qui non mi sembra proprio che siano facili da leggere o da capire. Penso che sia meglio metterlo in una funzione che descriva ciò che fa.
Craig,

2
Con le funzioni di freccia: array.map( o => o.age).filter( (v,i,a) => a.indexOf(v)===i). Uso la parola chiave funzione così raramente ora che devo leggere le cose due volte quando la vedo 😊
Drenai,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.