recorrer - Longitud de un objeto JavaScript
recorrer array de objetos javascript (30)
Si tengo un objeto JavaScript, di
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
¿Existe una forma de práctica recomendada o aceptada para obtener la longitud de este objeto?
@palmsey: Para ser justos con el OP, los documentos de javascript en realidad se refieren explícitamente a usar variables de tipo Objeto de esta manera como "matrices asociativas".
Y para ser justos con @palmsey, estaba en lo cierto, no son matrices asociativas, definitivamente son objetos :) - haciendo el trabajo de una matriz asociativa. Pero en lo que respecta al punto más amplio, definitivamente parece tener el derecho de acuerdo con este excelente artículo que encontré:
JavaScript "matrices asociativas" considerado perjudicial
Pero de acuerdo con todo esto, ¿no es la respuesta aceptada en sí una mala práctica?
Especifique una función de tamaño de prototipo () para Objeto
Si se ha agregado algo más al objeto .prototipo, el código sugerido fallará:
<script type="text/javascript">
Object.prototype.size = function () {
var len = this.length ? --this.length : -1;
for (var k in this)
len++;
return len;
}
Object.prototype.size2 = function () {
var len = this.length ? --this.length : -1;
for (var k in this)
len++;
return len;
}
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
alert("age is " + myArray["age"]);
alert("length is " + myArray.size());
</script>
No creo que esa respuesta sea la aceptada, ya que no se puede confiar en que funcione si tiene otro código ejecutándose en el mismo contexto de ejecución. Para hacerlo de manera robusta, seguramente necesitaría definir el método de tamaño dentro de myArray y verificar el tipo de miembros a medida que los recorre.
Propiedad
Object.defineProperty(Object.prototype, ''length'', {
get: function () {
var size = 0, key;
for (key in this)
if (this.hasOwnProperty(key))
size++;
return size;
}
});
Utilizar
var o = {a: 1, b: 2, c: 3};
alert(o.length); // <-- 3
o[''foo''] = 123;
alert(o.length); // <-- 4
¿Qué tal algo como esto?
function keyValuePairs() {
this.length = 0;
function add(key, value) { this[key] = value; this.length++; }
function remove(key) { if (this.hasOwnProperty(key)) { delete this[key]; this.length--; }}
}
A continuación se muestra una versión de la respuesta de James Coglan en CoffeeScript para aquellos que han abandonado el JavaScript directo :)
Object.size = (obj) ->
size = 0
size++ for own key of obj
size
Aquí está la solución más trans-navegador.
Esto es mejor que la respuesta aceptada porque utiliza Object.keys nativos, si existen. Por lo tanto, es el más rápido para todos los navegadores modernos.
if (!Object.keys) {
Object.keys = function (obj) {
var arr = [],
key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
arr.push(key);
}
}
return arr;
};
}
Object.keys(obj).length;
Aquí hay una solución completamente diferente que solo funcionará en navegadores más modernos (IE9 +, Chrome, Firefox 4+, Opera 11.60+, Safari 5.1+)
Ver jsFiddle
Configura tu clase de Array Asociativo
/**
* @constructor
*/
AssociativeArray = function () {};
// Make the length property work
Object.defineProperty(AssociativeArray.prototype, "length", {
get: function () {
var count = 0;
for (var key in this) {
if (this.hasOwnProperty(key))
count++;
}
return count;
}
});
Ahora puedes usar este código de la siguiente manera ...
var a1 = new AssociativeArray();
a1["prop1"] = "test";
a1["prop2"] = 1234;
a1["prop3"] = "something else";
alert("Length of array is " + a1.length);
Aquí hay una versión diferente de la respuesta de James Cogan. En lugar de pasar un argumento, simplemente prototipo de la clase Objeto y haga el código más limpio.
Object.prototype.size = function () {
var size = 0,
key;
for (key in this) {
if (this.hasOwnProperty(key)) size++;
}
return size;
};
var x = {
one: 1,
two: 2,
three: 3
};
x.size() === 3;
Ejemplo de jsfiddle: http://jsfiddle.net/qar4j/1/
Aquí le indicamos cómo y no se olvide de verificar que la propiedad no esté en la cadena del prototipo:
var element_count = 0;
for(var e in myArray)
if(myArray.hasOwnProperty(e))
element_count++;
El mas simple es
Object.keys(myObject).length
Este método obtiene todos los nombres de propiedad de su objeto en una matriz, por lo que puede obtener la longitud de esa matriz que es igual a la longitud de las claves de su objeto.
Object.getOwnPropertyNames({"hi":"Hi","msg":"Message"}).length; // => 2
La forma más sencilla es así.
Object.keys(myobject).length
donde myobject es el objeto de lo que quieres la longitud
La respuesta más robusta (es decir, que captura la intención de lo que intentas hacer mientras causas el menor número de errores) sería:
Object.size = function(obj) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
// Get the size of an object
var size = Object.size(myObj);
Hay una especie de convención en JavaScript que no agrega cosas al Object.prototype , porque puede romper enumeraciones en varias bibliotecas. Sin embargo, agregar métodos al Objeto generalmente es seguro.
Aquí hay una actualización a partir de 2016 y un
amplio despliegue de ES5
y más allá.
Para IE9 + y todos los demás navegadores modernos compatibles con ES5 +, puedes usar
Object.keys()
por lo que el código anterior se convierte en:
var size = Object.keys(myObj).length;
Esto no tiene que modificar ningún prototipo existente ya que
Object.keys()
ahora está integrado.
Edición : los objetos pueden tener propiedades simbólicas que no se pueden devolver a través del método Object.key. Entonces la respuesta sería incompleta sin mencionarlas.
El tipo de símbolo se agregó al idioma para crear identificadores únicos para las propiedades del objeto. El principal beneficio del tipo de símbolo es la prevención de sobreescrituras.
Object.keys
o
Object.getOwnPropertyNames
no funciona para las propiedades simbólicas.
Para devolverlos necesitas usar
Object.getOwnPropertySymbols
.
var person = {
[Symbol(''name'')]: ''John Doe'',
[Symbol(''age'')]: 33,
"occupation": "Programmer"
};
const propOwn = Object.getOwnPropertyNames(person);
console.log(propOwn.length); // 1
let propSymb = Object.getOwnPropertySymbols(person);
console.log(propSymb.length); // 2
No soy un experto en JavaScript, pero parece que tendrías que recorrer los elementos y contarlos, ya que Object no tiene un método de longitud:
var element_count = 0;
for (e in myArray) { if (myArray.hasOwnProperty(e)) element_count++; }
@palmsey: Para ser justos con el OP, la documentación de JavaScript en realidad se refiere explícitamente a usar variables de tipo Objeto de esta manera como "matrices asociativas".
Para algunos casos es mejor simplemente almacenar el tamaño en una variable separada. Especialmente, si está agregando a la matriz un elemento en un lugar y puede incrementar fácilmente el tamaño. Obviamente, funcionaría mucho más rápido si necesita comprobar el tamaño a menudo.
Para no meterse con el prototipo u otro código, puede construir y extender su propio objeto:
function Hash(){
var length=0;
this.add = function(key, val){
if(this[key] == undefined)
{
length++;
}
this[key]=val;
};
this.length = function(){
return length;
};
}
myArray = new Hash();
myArray.add("lastname", "Simpson");
myArray.add("age", 21);
alert(myArray.length()); // will alert 2
Si siempre usas el método add, la propiedad length será correcta. Si le preocupa que usted u otras personas se olviden de usarlo, también puede agregar el contador de propiedades que los demás han publicado al método de longitud.
Por supuesto, siempre se podrían sobrescribir los métodos. Pero incluso si lo hace, su código probablemente fallaría notablemente, lo que facilitaría la depuración. ;)
Podemos encontrar la longitud del Objeto usando:
Object.values(myObject).length
Si está utilizando AngularJS 1.x, puede hacer las cosas de la manera AngularJS creando un filtro y utilizando el código de cualquiera de los otros ejemplos, como los siguientes:
// Count the elements in an object
app.filter(''lengthOfObject'', function() {
return function( obj ) {
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
}
})
Uso
En su controlador:
$scope.filterResult = $filter(''lengthOfObject'')($scope.object)
O en su opinión:
<any ng-expression="object | lengthOfObject"></any>
Si necesita una estructura de datos asociativa que exponga su tamaño, utilice mejor un mapa en lugar de un objeto.
var myMap = new Map();
myMap.set("firstname", "Gareth");
myMap.set("lastname", "Simpson");
myMap.set("age", 21);
myMap.size; // 3
Si no le importa que sea compatible con Internet Explorer 8 o una versión inferior, puede obtener fácilmente el número de propiedades en un objeto aplicando los siguientes dos pasos:
-
Ejecute
developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
para obtener una matriz que contenga los nombres de solo aquellas propiedades que son
enumerable
o
Object.getOwnPropertyNames()
si también desea incluir los nombres de las propiedades que no son enumerables. -
Obtener la propiedad
.length
de esa matriz.
Si necesita hacer esto más de una vez, podría incluir esta lógica en una función:
function size(obj, enumerablesOnly) {
return enumerablesOnly === false ?
Object.getOwnPropertyNames(obj).length :
Object.keys(obj).length;
}
Cómo utilizar esta función particular:
var myObj = Object.create({}, {
getFoo: {},
setFoo: {}
});
myObj.Foo = 12;
var myArr = [1,2,5,4,8,15];
console.log(size(myObj)); // Output : 1
console.log(size(myObj, true)); // Output : 1
console.log(size(myObj, false)); // Output : 3
console.log(size(myArr)); // Output : 6
console.log(size(myArr, true)); // Output : 6
console.log(size(myArr, false)); // Output : 7
Vea también este violín para una demostración.
Si sabe que no tiene que preocuparse por
hasOwnProperty
comprobaciones de
hasOwnProperty
de la
hasOwnProperty
, puede hacerlo de manera muy simple:
Object.keys(myArray).length
Si tenemos el hash
hash = {"a": "b", "c": "d"};
podemos obtener la longitud utilizando la longitud de las claves, que es la longitud del hash:
teclas (hash) .length
Siempre puede hacer
Object.getOwnPropertyNames(myObject).length
para obtener el mismo resultado que daría a
[].length
para la matriz normal.
Simplemente puede usar
Object.keys(obj).length
en cualquier objeto para obtener su longitud.
Object.keys devuelve una matriz que contiene todas las
claves de
objeto (propiedades) que pueden ser útiles para encontrar la longitud de ese objeto utilizando la longitud de la matriz correspondiente.
Incluso puedes escribir una
función
para esto.
Seamos
creativos
y también escribamos un
método
para ello (junto con una propiedad getter más conveniente):
function objLength(obj)
{
return Object.keys(obj).length;
}
console.log(objLength({a:1, b:"summit", c:"nonsense"}));
// Works perfectly fine
var obj = new Object();
obj[''fish''] = 30;
obj[''nullified content''] = null;
console.log(objLength(obj));
// It also works your way, which is creating it using the Object constructor
Object.prototype.getLength = function() {
return Object.keys(this).length;
}
console.log(obj.getLength());
// You can also write it as a method, which is more efficient as done so above
Object.defineProperty(Object.prototype, "length", {get:function(){
return Object.keys(this).length;
}});
console.log(obj.length);
// probably the most effictive approach is done so and demonstrated above which sets a getter property called "length" for objects which returns the equivalent value of getLength(this) or this.getLength()
Simplemente use esto para obtener la
length
:
Object.keys(myObject).length
Un poco tarde para el juego, pero una buena manera de lograrlo (solo IE9 +) es definir un captador de magia en la propiedad length:
Object.defineProperty(Object.prototype, "length", {
get: function () {
return Object.keys(this).length;
}
});
Y puedes usarlo así:
var myObj = { ''key'': ''value'' };
myObj.length;
Daría
1
.
Una variación de algunos de los anteriores es:
var objLength = function(obj){
var key,len=0;
for(key in obj){
len += Number( obj.hasOwnProperty(key) );
}
return len;
};
Es una forma un poco más elegante de integrar hasOwnProp.
Utilizar:
var myArray = new Object();
myArray["firstname"] = "Gareth";
myArray["lastname"] = "Simpson";
myArray["age"] = 21;
obj = Object.keys(myArray).length;
console.log(obj)
<script>
myObj = {"key1" : "Hello", "key2" : "Goodbye"};
var size = Object.keys(myObj).length;
console.log(size);
</script>
<p id="myObj">The number of <b>keys</b> in <b>myObj</b> are: <script>document.write(size)</script></p>
Esto funciona para mí:
var size = Object.keys(myObj).length;
Actualizado : si estás usando Underscore.js (recomendado, ¡es liviano!), Entonces puedes hacerlo
_.size({one : 1, two : 2, three : 3});
=> 3
Si no , y no quieres perder el tiempo con las propiedades del Objeto por cualquier razón, y ya estás usando jQuery, un complemento es igualmente accesible:
$.assocArraySize = function(obj) {
// http://.com/a/6700/11236
var size = 0, key;
for (key in obj) {
if (obj.hasOwnProperty(key)) size++;
}
return size;
};
var myObject = new Object();
myObject["firstname"] = "Gareth";
myObject["lastname"] = "Simpson";
myObject["age"] = 21;
- Object.values (myObject) .length
- Object.entries (myObject) .length
- Object.keys (myObject) .length