¿Cómo obtener valores distintos de una matriz de objetos en JavaScript?

385

Suponiendo que tengo lo siguiente:

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

¿Cuál es la mejor manera de poder obtener una matriz de todas las edades distintas de modo que obtenga una matriz de resultados de:

[17, 35]

¿Hay alguna forma de estructurar alternativamente los datos o un método mejor de tal manera que no tenga que repetir cada matriz comprobando el valor de "edad" y comparar con otra matriz para su existencia, y agregarlo si no?

Si hubiera alguna manera, podría extraer las distintas edades sin iterar ...

De manera ineficaz actual me gustaría mejorar ... Si eso significa que en lugar de "matriz" ser una matriz de objetos, pero un "mapa" de objetos con alguna clave única (es decir, "1,2,3") sería esta bien tambien Solo estoy buscando la forma más eficiente de rendimiento.

Lo siguiente es cómo lo hago actualmente, pero para mí, la iteración parece ser mala para la eficiencia a pesar de que funciona ...

var distinct = []
for (var i = 0; i < array.length; i++)
   if (array[i].age not in distinct)
      distinct.push(array[i].age)
Rolando
fuente
34
la iteración no es "mala para la eficiencia" y no puede hacer nada a cada elemento "sin iterar". puede usar varios métodos de aspecto funcional, pero en última instancia, algo en algún nivel tiene que iterar sobre los elementos.
Eevee
// Código de ejecución al 100% const listOfTags = [{id: 1, etiqueta: "Hola", color: "rojo", clasificación: 0}, {id: 2, etiqueta: "Mundo", color: "verde", clasificación : 1}, {id: 3, etiqueta: "Hola", color: "azul", clasificación: 4}, {id: 4, etiqueta: "Sol", color: "amarillo", clasificación: 5}, {id : 5, etiqueta: "Hola", color: "rojo", clasificación: 6}], claves = ['etiqueta', 'color'], filtrado = listOfTags.filter ((s => o => (k => ! s.has (k) && s.add (k)) (keys.map (k => o [k]). join ('|'))) (new Set)); console.log (filtrado);
Sandeep Mishra
1
la recompensa es excelente, pero la pregunta con los datos y la respuesta dados ya está respondida aquí: stackoverflow.com/questions/53542882/… . ¿Cuál es el propósito de la recompensa? ¿Debo responder a este problema particular con dos o más claves?
Nina Scholz
Setobjeto mapys son derrochadores. Este trabajo solo toma una .reduce()etapa simple .
Reducido el

Respuestas:

127

Si esto fuera PHP, construiría una matriz con las claves y las tomaría array_keysal final, pero JS no tiene ese lujo. En cambio, intente esto:

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);
}
Niet the Dark Absol
fuente
15
No, porque array_uniquecompararía todo el artículo, no solo la edad como se solicita aquí.
Niet the Dark Absol
66
Creo que flags = {}es mejor queflags = []
zhuguowei
3
@zhuguowei tal vez, aunque no hay nada realmente malo con las matrices dispersas, y también asumí que agees un número entero relativamente pequeño (<120 seguramente)
Niet the Dark Absol
¿Cómo podríamos imprimir también el número total de personas que tienen la misma edad?
user1788736
608

Si está utilizando ES6 / ES2015 o posterior, puede hacerlo de esta manera:

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

Aquí hay un ejemplo de cómo hacerlo.

Vlad Bezden
fuente
11
Me sale un error:TypeError: (intermediate value).slice is not a function
AngJobs en Github
77
@Thomas ... significa operador de propagación. En este caso, significa crear un nuevo conjunto y difundirlo en una lista. Puede encontrar más información al respecto aquí: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Vlad Bezden
10
para el mecanografiado, debe usar un nuevo conjunto envuelto en Array.from () ... proporcionaré esa respuesta a continuación. @AngJobs
Christian Matthew
44
¿Es posible encontrar objetos únicos basados ​​en múltiples claves en el objeto?
Jefree Sujit
14
Esta solución fue dada casi literalmente unos meses antes por @Russell Vea. ¿Revisó las respuestas existentes? Pero, de nuevo, más de 266 votos muestran que nadie más lo hizo.
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]
Ivan Nosov
fuente
2
Si quiero obtener el valor con su índice, entonces ¿cómo puedo obtener? Ejemplo: Quiero obtener {"nombre": "Bob", "edad": "17"}, {"nombre": "Bob", "edad ":" 17 "}
Abdullah Al Mamun
10
Es por eso que debes seguir desplazándote
Alejandro Bastidas
55
@AbdullahAlMamun puedes usar el mapa en .filter en lugar de llamar a .map primero, así:array.filter((value, index, self) => self.map(x => x.age).indexOf(value.age) == index)
Leo
1
ps: .map dentro de .filter puede ser lento, así que tenga cuidado con las matrices grandes
Leo
2
@IvanNosov su fragmento es muy bueno, aunque varias líneas de explicación de cómo funciona con punteros para mapear y filtrar la documentación lo harán perfecto y claro para principiantes
azakgaim
128

Podría usar un enfoque de diccionario como este. Básicamente, asigna el valor que desea que sea distinto como clave en el "diccionario" (aquí usamos una matriz como un objeto para evitar el modo diccionario). Si la clave no existía, entonces agrega ese valor como distinto.

Aquí hay una demostración funcional:

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>

Esto será O (n) donde n es el número de objetos en la matriz ym es el número de valores únicos. No hay una forma más rápida que O (n) porque debe inspeccionar cada valor al menos una vez.

La versión anterior de esto utilizaba un objeto, y para in. Estos eran de naturaleza menor, y desde entonces se han actualizado anteriormente. Sin embargo, la razón de un aparente avance en el rendimiento entre las dos versiones en el jsperf original se debe a que el tamaño de la muestra de datos es muy pequeño. Por lo tanto, la comparación principal en la versión anterior fue observar la diferencia entre el mapa interno y el uso del filtro versus las búsquedas en modo diccionario.

He actualizado el código anterior, como se señaló, sin embargo, también he actualizado jsperf para mirar a través de 1000 objetos en lugar de 3. 3 pasó por alto muchos de los escollos de rendimiento involucrados ( jsperf obsoleto ).

Actuación

https://jsperf.com/filter-vs-dictionary-more-data Cuando ejecuté este diccionario fue un 96% más rápido.

filtro vs diccionario

Travis J
fuente
44
rápido y sin necesidad de complementos adicionales. Realmente genial
mihai
2
¿qué talif( typeof(unique[array[i].age]) == "undefined"){ distinct.push(array[i].age); unique[array[i].age] = 0; }
Timeless
77
Wow, el rendimiento realmente ha cambiado a favor de la opción de mapa. Haga clic en ese enlace jsperf!
AL
1
@ 98percentmonkey: el objeto se utilizó para facilitar el "enfoque del diccionario". Dentro del objeto, cada aparición que se rastrea se agrega como una clave (o un contenedor). De esta manera, cuando nos encontramos con una ocurrencia, podemos verificar si la clave (o bin) existe; si existe, sabemos que la ocurrencia no es única; si no existe, sabemos que la ocurrencia es única y la agregamos.
Travis J
1
@ 98percentmonkey: la razón para usar un objeto es que la búsqueda es O (1) ya que busca el nombre de una propiedad una vez, mientras que una matriz es O (n) ya que tiene que mirar cada valor para verificar la existencia. Al final del proceso, el conjunto de claves (bins) en el objeto representa el conjunto de ocurrencias únicas.
Travis J
91

Así es como resolvería esto usando el nuevo Set a través de ES6 para Typecript a partir del 25 de agosto de 2017

Array.from(new Set(yourArray.map((item: any) => item.id)))
Christian Matthew
fuente
3
esto ayudó, fue obteniendo antes gracias. El tipo 'Set' no es un tipo de matriz
robert king
1
Esta es una respuesta genial. Hasta que me desplacé a este, iba a escribir una respuesta diciendo: Object.keys (values.reduce <any> ((x, y) => {x [y] = null; return x;}, {} )); Pero esta respuesta es más concisa y se aplica a todos los tipos de datos en lugar de solo cadenas.
jgosar
1
¡Esta respuesta es espectacular!
lukeocodes
79

Con las funciones de ES6, puede hacer algo como:

const uniqueAges = [...new Set( array.map(obj => obj.age)) ];
Russell Vea
fuente
66
Este enfoque solo funcionará en tipos primitivos (que es el caso aquí ya que las edades son una serie de números) pero fallará para los objetos.
k0pernikus
¿Alguna idea de cómo hacer que funcione para objetos con dos teclas?
cegprakash
1
Algo así comoconst uniqueObjects = [ ...new Set( array.map( obj => obj.age) ) ].map( age=> { return array.find(obj => obj.age === age) } )
Harley B
62

Simplemente mapearía y eliminaría dups:

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]

Editar: Aight! No es la forma más eficiente en términos de rendimiento, sino la IMO más simple y legible. Si realmente le interesa la microoptimización o tiene grandes cantidades de datos, un forciclo regular será más "eficiente".

elclanrs
fuente
3
@elclanrs - "la forma más eficiente de rendimiento" - Este enfoque es lento .
Travis J
1
@ Evee: Ya veo. La versión de subrayado en su respuesta tampoco es muy rápida , quiero decir, al final elige lo que es más conveniente, dudo que 1-30% más o menos refleje una "gran mejora" en las pruebas genéricas y cuando OP / s son miles .
elclanrs
44
bueno seguro. con solo tres elementos , lo más rápido es hacer tres variables y usar algunos ifs. obtendrás resultados muy diferentes con tres millones.
Eevee
1
no rápido, pero en mi caso funcionó, ya que no estoy tratando con un gran conjunto de datos, gracias.
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'));

Ejemplo 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]
oleg gabureac
fuente
66
Si bien este código puede responder la pregunta, proporcionar un contexto adicional sobre cómo y por qué resuelve el problema mejoraría el valor a largo plazo de la respuesta.
Alexander
El primero que usa indexOf vs index es simplemente brillante.
alas
Tenga en cuenta que esto solo funciona para valores primitivos. Si tiene una variedad de fechas, necesita algunos métodos más personalizados. Lea más aquí: codeburst.io/javascript-array-distinct-5edc93501dc4
Molx
36

Para aquellos que desean devolver objetos con todas las propiedades únicas por clave

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.

Arun Kumar Saini
fuente
2
Nota: esto seleccionará el último elemento duplicado en la lista.
Eugene Kulabuhov
1
Agregando esto a la respuesta!
Arun Kumar Saini
1
Exactamente lo que estaba buscando. ¡Muchas gracias por compartir!
Devner
1
¡Creo que esta debería ser la MEJOR respuesta para ser honesto!
Jaroslav Benc
26

Ya hay muchas respuestas válidas, pero quería agregar una que use solo el reduce()método porque es limpio y simple.

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

Úselo así:

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

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

La forEachversión de la respuesta de @ travis-j (útil en los navegadores modernos y el mundo Node JS):

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

34% más rápido en Chrome v29.0.1547: http://jsperf.com/filter-versus-dictionary/3

Y una solución genérica que toma una función de mapeador (un poco más lento que el mapa directo, pero eso es de esperar):

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]
Mrchief
fuente
1
Me gusta más la solución genérica, ya que es poco probable que la edad sea el único valor distinto que se necesita en un escenario del mundo real.
Toft
55
En el genérico, cambie "distinct.push (key)" a "distinct.push (x)" para devolver una lista de los elementos reales, ¡lo cual me parece muy útil!
Silas Hansen
15

He empezado a poner a subrayado Underscore en todos los proyectos nuevos de forma predeterminada para no tener que pensar en estos pequeños problemas de mezcla de datos.

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].

Eevee
fuente
13

Aquí hay otra forma de resolver esto:

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

No tengo idea de qué tan rápido se compara esta solución con las otras, pero me gusta el aspecto más limpio. ;-)


EDITAR: Bien, lo anterior parece ser la solución más lenta de todas aquí.

He creado un caso de prueba de rendimiento aquí: http://jsperf.com/distinct-values-from-array

En lugar de probar las edades (enteros), elegí comparar los nombres (cadenas).

El método 1 (solución de TS) es muy rápido. Curiosamente, el Método 7 supera a todas las demás soluciones, aquí me acabo de deshacer de .indexOf () y utilicé una implementación "manual" del mismo, evitando llamadas a funciones en bucle:

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 diferencia en el rendimiento con Safari y Firefox es sorprendente, y parece que Chrome hace el mejor trabajo en optimización.

No estoy exactamente seguro de por qué los fragmentos anteriores son tan rápidos en comparación con los demás, tal vez alguien más sabio que yo tenga una respuesta. ;-)

BaM
fuente
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]
Ivan Nosov
fuente
2
¿Puedes explicar cómo hacer esto con javascript simple como está implícito en la pregunta?
Ruskin
es una función de subrayado _.chain
vini
2
pero pluck () no está en lodash.
Yash Vekaria
1
_.chain (array) .map ('edad'). unique (). value (); trabajó para mi.
Yash Vekaria
la versión 4.0 tuvo algunos cambios importantes - 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();

Devoluciones [17,35]

Yash Vekaria
fuente
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;
}
Dmitriy Kupriyanov
fuente
5

underscore.js _.uniq(_.pluck(array,"age"))

Radosław Kopczyński
fuente
55
Agregue una explicación de cómo esto responde la pregunta.
Gato robótico
2
_.pluck ha sido eliminado a favor de _.map
Ajax3.14
5

Aquí hay una solución versátil que utiliza reduce, permite el mapeo y mantiene el orden de inserción.

elementos : una matriz

asignador : una función unaria que asigna el elemento a los criterios, o vacía para asignar el elemento en sí.

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);

Puede agregar esto a su prototipo de matriz y omitir el parámetro de elementos si ese es su estilo ...

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

También puede usar un conjunto en lugar de una matriz para acelerar la coincidencia.

function distinct(items, mapper) {
    if (!mapper) mapper = (item)=>item;
    return items.map(mapper).reduce((acc, item) => {
        acc.add(item);
        return acc;
    }, new Set());
}
Steven Spungin
fuente
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' } 
]
*/

Ruben Morales Felix
fuente
2
esto se parece a O (n ^ 2)
cegprakash 05 de
4

Acabo de encontrar esto y pensé que es útil

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

Nuevamente usando subrayado , así que si tienes un objeto como este

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

te dará solo los objetos únicos.

Lo que sucede aquí es que indexBydevuelve un mapa como este

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

y solo porque es un mapa, todas las claves son únicas.

Entonces solo estoy asignando esta lista de nuevo a la matriz.

En caso de que solo necesite los valores distintos

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

Tenga en cuenta que keyse devuelve como una cadena, por lo que si necesita números enteros, debe hacerlo

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

Creo que estás buscando la función 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 resultado:

17,35

Demostración de jsFiddle: http://jsfiddle.net/4J2SX/201/

Amil Sajeev
fuente
3

Si, como yo, prefiere una opción más "funcional" sin comprometer la velocidad, este ejemplo utiliza una búsqueda rápida del diccionario envuelta en el interior para reducir el cierre.

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]
    }
}, [{},[]])

Según esta prueba, mi solución es dos veces más rápida que la respuesta propuesta

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

Sé que mi código tiene poca longitud y poca complejidad de tiempo, pero es comprensible, así que lo intenté de esta manera.

Estoy tratando de desarrollar una función basada en prototipos aquí y el código también cambia.

Aquí, Distinct es mi propia función 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>

Prabhat
fuente
2

Si tiene Array.prototype.includes o está dispuesto a rellenarlo , esto funciona:

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

El siguiente código mostrará la matriz única de edades, así como la nueva matriz que no tiene edad duplicada

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);```
Shridhar Sagari
fuente
1

Escribí el mío en TypeScript, para un caso genérico, como el de 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)));
}

Donde Ues hashable, por supuesto. Para los objetos, es posible que necesite https://www.npmjs.com/package/es6-json-stable-stringify

Polv
fuente
1

En caso de que necesite un objeto entero único

const _ = require('lodash');

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

_.uniqWith(objects, _.isEqual);

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

cegprakash
fuente
votante negativo: ¿Te importaría explicar por qué el voto negativo?
cegprakash
1

Responder esta vieja pregunta no tiene sentido, pero hay una respuesta simple que habla de la naturaleza de Javascript. Los objetos en Javascript son inherentemente tablas hash. Podemos usar esto para obtener un hash de claves únicas:

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

Entonces podemos reducir el hash a una matriz de valores únicos:

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

Eso es todo lo que necesitas. La matriz a2 contiene solo las edades únicas.

Preston L. Bannister
fuente
1

Simple línea con gran rendimiento. 6% más rápido que las soluciones ES6 en mis pruebas .

var ages = array.map(function(o){return o.age}).filter(function(v,i,a) {
    return a.indexOf(v)===i
});
Craig
fuente
@ Jeb50 ¿Le importa agregar una línea múltiple que sea fácil de leer? Mirando a los demás aquí, realmente no siento que sean fáciles de leer o entender. Creo que es mejor colocar esto en una función que describa lo que hace.
Craig
2
Con funciones de dirección: array.map( o => o.age).filter( (v,i,a) => a.indexOf(v)===i). Utilizo la palabra clave de función tan raramente ahora que tengo que leer las cosas dos veces cuando la veo 😊
Drenai