Checking if an arbitrary value is symmetric - javascript

Task:
Give you an obj, it can be 3 types: string, number and number array, Check that they are symmetrical or not, return a Boolean value.
Example:
obj="" return true (Empty string should return true)
obj="1" return true (one char should return true)
obj="11" return true
obj="12" return false
obj="121" return true
obj=1 return true (number<10 should return true)
obj=-1 return false (negative number should return false)
obj=121 return true
**obj=[] return true (Empty array should return true)**
**obj=[1] return true (an array with one element should return true)**
obj=[1,2,3,4,5] return false
**obj=[1,2,3,2,1] return true**
**obj=[11,12,13,12,11] return true (left element = right element)**
obj=[11,12,21,11] return false (not verify them as a string)
My code fails the bolded ones and I've tried to work out why for ages!
Here's my code:
function sc(obj){
var obj2= obj;
if (obj==="") {
return true;
} else if (typeof obj === "string") {
var revd = obj.split("").reverse("").join("");
return revd === obj;
} else if (typeof obj === "number") {
var revd = parseInt(obj.toString().split("").reverse("").join(""));
return revd === obj;
} else if (typeof obj === "object") {
var obj2 = []
for (var i = obj.length-1; i >= 0; i--) {
obj2.push(obj[i])
}
return obj==obj2;
}
}
console.log(sc([11,12,13,12,11]));
Could anyone give me a hint as to what's going wrong?

instead of return obj==obj2;
write the following:
for (var i=0; i<obj.length, i++) {
if (obj[i] != obj2[i]) { return false; }
}
return true;

You cannot compare arrays like that since they are references. You can however, create a function for comparing them like this:
function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length)
return false;
for(var i = arr1.length; i--;) {
if(arr1[i] !== arr2[i])
return false;
}
return true;
}
And then use it like this:
function arraysEqual(arr1, arr2) {
if(arr1.length !== arr2.length)
return false;
for(var i = arr1.length; i--;) {
if(arr1[i] !== arr2[i])
return false;
}
return true;
}
function sc(obj){
var obj2= obj;
if (obj==="") {
return true;
} else if (typeof obj === "string") {
var revd = obj.split("").reverse("").join("");
return revd === obj;
} else if (typeof obj === "number") {
var revd = parseInt(obj.toString().split("").reverse("").join(""));
return revd === obj;
} else if (typeof obj === "object") {
var obj2 = []
for (var i = obj.length-1; i >= 0; i--) {
obj2.push(obj[i])
}
return arraysEqual(obj, obj2);
}
}
console.log(sc([11,12,13,12,11]));

Just iterate forward and backward at the same time and check.
Here is a alrothim written in c, easy to convert to C++.
Checking if an array in C is symmetric
(Javascript makes life easy re-write to JavaScript and use !=)

Related

Javascript: Deep comparison of object function syntax error

I am writing a recursive function for doing a deep comparison of two objects. However, I am getting a syntax error.
this is the function:
function deepEqual(obj1, obj2) {
if (compareArrays(Object.keys(obj1), Object.keys(obj2))){
for (let x of Object.keys(obj1)){
if (typeOf obj1.x == 'object' && typeOf obj2.x == 'object')\
return deepEqual(obj1.x, obj2.x)
else{
if (obj1.x !== obj2.x) return false
}
}
return true
}
else{
return false
}
}
this is the function compareArrays(this has no errors):
function compareArrays(array1, array2) {
if (array2.length === array1.length) {
for (var i = array2.length - 1; i >= 0; i--) {
if (array2[i] !== array1[i]){
return false
}
}
return true
}
else{
return false
}
}
Expected output:
true/false
Actual output:
if (typeOf obj1.x == 'object' && typeOf obj2.x == 'object') return deepEqual(obj1.x, obj2.x)
^^^^
SyntaxError: Unexpected identifier
You mistyped typeof and also \ is useless
Try this
function deepEqual(obj1, obj2) {
if (compareArrays(Object.keys(obj1), Object.keys(obj2))){
for (let x of Object.keys(obj1)){
if (typeof obj1.x == 'object' && typeof obj2.x == 'object')
return deepEqual(obj1.x, obj2.x)
else{
if (obj1.x !== obj2.x) return false
}
}
return true
}
else{
return false
}
}

How to check if object is empty in javascript for all levels in object

I wanted to find out if my object is empty or not for all its nested objects and key-value pairs.
for e.g.,
const x = {
a:"",
b:[],
c:{
x:[]
},
d:{
x:{
y:{
z:""
}
}
}
};
this should be an empty object and if any of this contains single value then it should be non empty.
Here is the way to do what using recursion
const x = {
a:"",
b:[],
c:{
x:[]
},
d:{
x:{
y:{
z:''
}
}
}
};
function checkEmpty(obj){
for(let key in obj){
//if the value is 'object'
if(obj[key] instanceof Object === true){
if(checkEmpty(obj[key]) === false) return false;
}
//if value is string/number
else{
//if array or string have length is not 0.
if(obj[key].length !== 0) return false;
}
}
return true;
}
console.log(checkEmpty(x))
x.d.x.y.z = 0;
console.log(checkEmpty(x));
You can write a recursive function like following. Function creates a set with 2 possible values true and false. If the size of set is 1 and the value being false, which mean that the object is empty.
const x = {a:"",b:[],c:{x:[]},d:{x:{y:{z:""}}}};
function isEmpty(o, r = new Set()) {
for (let k in o) {
if(typeof o[k] === "object") {
if(Array.isArray(o[k])) r.add(!!o[k].length);
else isEmpty(o[k],r);
} else r.add(!(o[k] === "" || o[k] === undefined || o[k] === null));
}
return r;
}
let result = isEmpty(x);
console.log(result.has(false) && result.size == 1);
I will use a recursive approach for this one, we iterate over the object.keys() and check is every value related to the key is empty, in the case the value is an object, we go one level deeper to check it.
const x = {
a:"",
b:[],
c:{x:[]},
d:{x:{y:{z:""}}}
};
const x1 = [0,0,0];
const x2 = {0:0,1:0,2:0};
const isEmpty = (obj, empty=true) =>
{
Object.keys(obj).forEach((key) =>
{
if (typeof obj[key] === "object")
empty = isEmpty(obj[key], empty);
else
empty = empty && (obj[key].length === 0);
// Return early if we detect empty here.
if (!empty) return empty;
});
return empty;
}
console.log("original x: ", isEmpty(x));
x.a = "I'm not empty";
console.log("x after edit: ", isEmpty(x));
console.log("x1: ", isEmpty(x1));
console.log("x2: ", isEmpty(x2));
try (we use here recursion, fat arrow, obj. keys, reduce, ternary operator and object checking)
let isEmpty = o => o.constructor.name === "Object" ?
Object.keys(o).reduce((y,z)=> y&&isEmpty(o[z]) ,true) : o.length == 0;
const x = {
a:"",
b:[],
c:{
x:[]
},
d:{
x:{
y:{
z:""
}
}
}
};
let isEmpty = o => o.constructor.name === "Object" ?
Object.keys(o).reduce((y,z)=> y&&isEmpty(o[z]) ,true) : o.length == 0;
// Test
console.log(isEmpty(x));
x.d.x.y.z="Smile to life and life will smile to you";
console.log(isEmpty(x));

Javascript what is the difference between var = null, and var = {} [duplicate]

This question already has answers here:
How do I test for an empty JavaScript object?
(48 answers)
Closed 5 years ago.
What is the fastest way to check if an object is empty or not?
Is there a faster and better way than this:
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
For ECMAScript5 (not supported in all browsers yet though), you can use:
Object.keys(obj).length === 0
I'm assuming that by empty you mean "has no properties of its own".
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
Examples:
isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true
isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false
If you only need to handle ECMAScript5 browsers, you can use Object.getOwnPropertyNames instead of the hasOwnProperty loop:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
This will ensure that even if the object only has non-enumerable properties isEmpty will still give you the correct results.
EDIT: Note that you should probably use ES5 solution instead of this since ES5 support is widespread these days. It still works for jQuery though.
Easy and cross-browser way is by using jQuery.isEmptyObject:
if ($.isEmptyObject(obj))
{
// do something
}
More: http://api.jquery.com/jQuery.isEmptyObject/
You need jquery though.
Underscore and lodash each have a convenient isEmpty() function, if you don't mind adding an extra library.
_.isEmpty({});
Lets put this baby to bed; tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:
(for...in...) is the fastest option to use!
Object.keys(obj).length is 10 times slower for empty objects
JSON.stringify(obj).length is always the slowest (not surprising)
Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).length can be much longer on some systems.
Bottom line performance wise, use:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
or
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Results under Node:
first result: return (Object.keys(obj).length === 0)
second result: for (var x in obj) { return false; }...
third result: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
forth result: return ('{}' === JSON.stringify(obj))
Testing for Object with 0 keys
0.00018
0.000015
0.000015
0.000324
Testing for Object with 1 keys
0.000346
0.000458
0.000577
0.000657
Testing for Object with 2 keys
0.000375
0.00046
0.000565
0.000773
Testing for Object with 3 keys
0.000406
0.000476
0.000577
0.000904
Testing for Object with 4 keys
0.000435
0.000487
0.000589
0.001031
Testing for Object with 5 keys
0.000465
0.000501
0.000604
0.001148
Testing for Object with 6 keys
0.000492
0.000511
0.000618
0.001269
Testing for Object with 7 keys
0.000528
0.000527
0.000637
0.00138
Testing for Object with 8 keys
0.000565
0.000538
0.000647
0.00159
Testing for Object with 100 keys
0.003718
0.00243
0.002535
0.01381
Testing for Object with 1000 keys
0.0337
0.0193
0.0194
0.1337
Note that if your typical use case tests a non empty object with few keys, and rarely do you get to test empty objects or objects with 10 or more keys, consider the Object.keys(obj).length option. - otherwise go with the more generic (for... in...) implementation.
Note that Firefox seem to have a faster support for Object.keys(obj).length and Object.getOwnPropertyNames(obj).length, making it a better choice for any non empty Object, but still when it comes to empty objects, the (for...in...) is simply 10 times faster.
My 2 cents is that Object.keys(obj).length is a poor idea since it creates an object of keys just to count how many keys are inside, than destroys it! In order to create that object he needs to loop overt the keys... so why use it and not the (for... in...) option :)
var a = {};
function timeit(func,count) {
if (!count) count = 100000;
var start = Date.now();
for (i=0;i<count;i++) func();
var end = Date.now();
var duration = end - start;
console.log(duration/count)
}
function isEmpty1() {
return (Object.keys(a).length === 0)
}
function isEmpty2() {
for (x in a) { return false; }
return true;
}
function isEmpty3() {
for (x in a) { if (a.hasOwnProperty(x)) return false; }
return true;
}
function isEmpty4() {
return ('{}' === JSON.stringify(a))
}
for (var j=0;j<10;j++) {
a = {}
for (var i=0;i<j;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4);
}
a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);
a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);
Elegant way - use keys
var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
function isEmpty( o ) {
for ( var p in o ) {
if ( o.hasOwnProperty( p ) ) { return false; }
}
return true;
}
var x= {}
var y= {x:'hi'}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)
true
false
http://jsfiddle.net/j7ona6hz/1/
Surprised to see so many weak answers on such a basic JS question... The top answer is no good too for these reasons:
it generates a global variable
returns true on undefined
uses for...in which is extremely slow by itself
function inside for...in is useless - return false without hasOwnProperty magic will work fine
In fact there's a simpler solution:
function isEmpty(value) {
return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}
https://lodash.com/docs#isEmpty comes in pretty handy:
_.isEmpty({}) // true
_.isEmpty() // true
_.isEmpty(null) // true
_.isEmpty("") // true
How bad is this?
function(obj){
for(var key in obj){
return false; // not empty
}
return true; // empty
}
No need for a library.
function(){ //must be within a function
var obj = {}; //the object to test
for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
return alert('not empty')//what ever you are trying to do once
return alert('empty'); //nope obj was empty do this instead;
}
It might be a bit hacky. You can try this.
if (JSON.stringify(data).length === 2) {
// Do something
}
Not sure if there is any disadvantage of this method.
fast onliner for 'dictionary'-objects:
function isEmptyDict(d){for (var k in d) return false; return true}
You can write a fallback if Array.isArray and Object.getOwnPropertyNames is not available
XX.isEmpty = function(a){
if(Array.isArray(a)){
return (a.length==0);
}
if(!a){
return true;
}
if(a instanceof Object){
if(a instanceof Date){
return false;
}
if(Object.getOwnPropertyNames(a).length == 0){
return true;
}
}
return false;
}
Imagine you have the objects below:
var obj1= {};
var obj2= {test: "test"};
Don't forget we can NOT use === sign for testing an object equality as they get inheritance, so If you using ECMA 5 and upper version of javascript, the answer is easy, you can use the function below:
function isEmpty(obj) {
//check if it's an Obj first
var isObj = obj !== null
&& typeof obj === 'object'
&& Object.prototype.toString.call(obj) === '[object Object]';
if (isObj) {
for (var o in obj) {
if (obj.hasOwnProperty(o)) {
return false;
break;
}
}
return true;
} else {
console.error("isEmpty function only accept an Object");
}
}
so the result as below:
isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object
funtion isEmpty(o,i)
{
for(i in o)
{
return!1
}
return!0
}
here's a good way to do it
function isEmpty(obj) {
if (Array.isArray(obj)) {
return obj.length === 0;
} else if (typeof obj === 'object') {
for (var i in obj) {
return false;
}
return true;
} else {
return !obj;
}
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isArray(a) {
return Object.prototype.toString.call(a) === '[object Array]'
}
function isObject(a) {
return Object.prototype.toString.call(a) === '[object Object]'
}
function isEmpty(a) {
if (null == a || "" == a)return!0;
if ("number" == typeof a || "string" == typeof a)return!1;
var b = !0;
if (isArray(a)) {
if (!a.length)return!0;
for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
return b
}
if (isObject(a)) {
for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
return b
}
return!0
}
May be you can use this decision:
var isEmpty = function(obj) {
for (var key in obj)
if(obj.hasOwnProperty(key))
return false;
return true;
}
I modified Sean Vieira's code to suit my needs. null and undefined don't count as object at all, and numbers, boolean values and empty strings return false.
'use strict';
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
var isObjectEmpty = function(obj) {
// null and undefined are not empty
if (obj == null) return false;
if(obj === false) return false;
if(obj === true) return false;
if(obj === "") return false;
if(typeof obj === "number") {
return false;
}
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
};
exports.isObjectEmpty = isObjectEmpty;
here my solution
function isEmpty(value) {
if(Object.prototype.toString.call(value) === '[object Array]') {
return value.length == 0;
} else if(value != null && typeof value === 'object') {
return Object.getOwnPropertyNames(value).length == 0;
} else {
return !(value || (value === 0));
}
}
Chears
if (Object.getOwnPropertyNames(obj1).length > 0)
{
alert('obj1 is empty!');
}

Implementing contains, which checks where the specified elements exists in the array or not is not working

I have tried this code to find if some object already exists in Array, but, it is not working:
function lote(pnIdLote,psNmLote, pnIdQuadro){
this.idlote = pnIdLote;
this.nmlote = psNmLote;
this.idquadro = pnIdQuadro;
}
Array.prototype.contains = function(obj){
var i = this.length;
while(i--){
console.log(i);
if (this[i] == obj) return true;
}
return false;
};
My code:
$(data).each(function(index){
if(this.idlote!=""){
loLote = new lote(this.idlote, this.nmlote, this.quadro);
if(!laLote.contains(loLote)){
laLote.push(loLote);
}
}
});
console.log(laLote);
The array appears this way:
[
lote
idlote: "2"
idquadro: "1"
nmlote: "Lote 1"
__proto__: lote
,
lote
idlote: "2"
idquadro: "1"
nmlote: "Lote 1"
__proto__: lote
,
lote
idlote: "2"
idquadro: "1"
nmlote: "Lote 1"
__proto__: lote
]
And I'd like an array with only one element, like this:
[
lote
idlote: "2"
idquadro: "1"
nmlote: "Lote 1"
__proto__: lote
]
Where do I fix my code?
Thanks,
Luciano
When a and b are objects in JavaScript, a == b or a === b is only true if a and b point to the same instance.
Example:
var a = [], b = [], c = a;
alert(a == b); // False
alert(a == c); // True
For your specific comparison method, I recommend creating a custom array constructor, to not pollute the Array object:
function lote() {} // Your lote constructor
var customArray = function() {
return Array.apply(this, arguments);
}
customArray.prototype = new Array;
customArray.prototype.contains = function(obj) {
var i = this.length;
// Not designed for non-"lote" instances, return null
if (!(obj instanceof lote)) return null;
while (i--) {
var current = this[i];
if (current.idlote === obj.idlote &&
current.nmlote === obj.nmlote &&
current.idquadro === obj.idquadrio) return true;
}
return false;
}
Instead of hard-coding the property names, you can also loop through the Object's properties, using Object.keys():
customArray.prototype.contains = function(obj) {
var i = this.length;
// Not designed for non-"lote" instances, return null
if (!(obj instanceof lote)) return null;
var keys = Object.keys(obj), keysLen = keys.length;
// Labeled loop
loop: while (i--) {
var current = this[i];
var len = keysLen, key;
for (len--) {
key = keys[len];
if (current[key] !== current[key]) {
len = -1;
continue loop; //Not equal, go to the next item in the outer loop
}
}
return true; // At this point, every property was equal.
}
return false;
}
Note that the shown method depends is based on the properties of the given obj. If it's not a valid lote object, the function returns null. Object.keys retrieves all properties of the given obj.
I think you should change the "contains" method to use Object.equals function, and you could use the code of
Array.prototype.contains = function(obj){
var i = this.length;
while(i--){
console.log(i);
if(this[i].equals(obj)) return true;
}
return false;
};
Object.prototype.equals = function(x){
var p;
for(p in this) {
if(typeof(x[p])=='undefined') {return false;}
}
for(p in this) {
if (this[p]) {
switch(typeof(this[p])) {
case 'object':
if (!this[p].equals(x[p])) { return false; } break;
case 'function':
if (typeof(x[p])=='undefined' ||
(p != 'equals' && this[p].toString() != x[p].toString()))
return false;
break;
default:
if (this[p] != x[p]) { return false; }
}
} else {
if (x[p])
return false;
}
}
for(p in x) {
if(typeof(this[p])=='undefined') {return false;}
}
return true;
}
Code of object comparison extracted from Object comparison in JavaScript

Is object empty? [duplicate]

This question already has answers here:
How do I test for an empty JavaScript object?
(48 answers)
Closed 5 years ago.
What is the fastest way to check if an object is empty or not?
Is there a faster and better way than this:
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
For ECMAScript5 (not supported in all browsers yet though), you can use:
Object.keys(obj).length === 0
I'm assuming that by empty you mean "has no properties of its own".
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
Examples:
isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true
isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false
If you only need to handle ECMAScript5 browsers, you can use Object.getOwnPropertyNames instead of the hasOwnProperty loop:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
This will ensure that even if the object only has non-enumerable properties isEmpty will still give you the correct results.
EDIT: Note that you should probably use ES5 solution instead of this since ES5 support is widespread these days. It still works for jQuery though.
Easy and cross-browser way is by using jQuery.isEmptyObject:
if ($.isEmptyObject(obj))
{
// do something
}
More: http://api.jquery.com/jQuery.isEmptyObject/
You need jquery though.
Underscore and lodash each have a convenient isEmpty() function, if you don't mind adding an extra library.
_.isEmpty({});
Lets put this baby to bed; tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:
(for...in...) is the fastest option to use!
Object.keys(obj).length is 10 times slower for empty objects
JSON.stringify(obj).length is always the slowest (not surprising)
Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).length can be much longer on some systems.
Bottom line performance wise, use:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
or
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Results under Node:
first result: return (Object.keys(obj).length === 0)
second result: for (var x in obj) { return false; }...
third result: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
forth result: return ('{}' === JSON.stringify(obj))
Testing for Object with 0 keys
0.00018
0.000015
0.000015
0.000324
Testing for Object with 1 keys
0.000346
0.000458
0.000577
0.000657
Testing for Object with 2 keys
0.000375
0.00046
0.000565
0.000773
Testing for Object with 3 keys
0.000406
0.000476
0.000577
0.000904
Testing for Object with 4 keys
0.000435
0.000487
0.000589
0.001031
Testing for Object with 5 keys
0.000465
0.000501
0.000604
0.001148
Testing for Object with 6 keys
0.000492
0.000511
0.000618
0.001269
Testing for Object with 7 keys
0.000528
0.000527
0.000637
0.00138
Testing for Object with 8 keys
0.000565
0.000538
0.000647
0.00159
Testing for Object with 100 keys
0.003718
0.00243
0.002535
0.01381
Testing for Object with 1000 keys
0.0337
0.0193
0.0194
0.1337
Note that if your typical use case tests a non empty object with few keys, and rarely do you get to test empty objects or objects with 10 or more keys, consider the Object.keys(obj).length option. - otherwise go with the more generic (for... in...) implementation.
Note that Firefox seem to have a faster support for Object.keys(obj).length and Object.getOwnPropertyNames(obj).length, making it a better choice for any non empty Object, but still when it comes to empty objects, the (for...in...) is simply 10 times faster.
My 2 cents is that Object.keys(obj).length is a poor idea since it creates an object of keys just to count how many keys are inside, than destroys it! In order to create that object he needs to loop overt the keys... so why use it and not the (for... in...) option :)
var a = {};
function timeit(func,count) {
if (!count) count = 100000;
var start = Date.now();
for (i=0;i<count;i++) func();
var end = Date.now();
var duration = end - start;
console.log(duration/count)
}
function isEmpty1() {
return (Object.keys(a).length === 0)
}
function isEmpty2() {
for (x in a) { return false; }
return true;
}
function isEmpty3() {
for (x in a) { if (a.hasOwnProperty(x)) return false; }
return true;
}
function isEmpty4() {
return ('{}' === JSON.stringify(a))
}
for (var j=0;j<10;j++) {
a = {}
for (var i=0;i<j;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4);
}
a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);
a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);
Elegant way - use keys
var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
function isEmpty( o ) {
for ( var p in o ) {
if ( o.hasOwnProperty( p ) ) { return false; }
}
return true;
}
var x= {}
var y= {x:'hi'}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)
true
false
http://jsfiddle.net/j7ona6hz/1/
Surprised to see so many weak answers on such a basic JS question... The top answer is no good too for these reasons:
it generates a global variable
returns true on undefined
uses for...in which is extremely slow by itself
function inside for...in is useless - return false without hasOwnProperty magic will work fine
In fact there's a simpler solution:
function isEmpty(value) {
return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}
https://lodash.com/docs#isEmpty comes in pretty handy:
_.isEmpty({}) // true
_.isEmpty() // true
_.isEmpty(null) // true
_.isEmpty("") // true
How bad is this?
function(obj){
for(var key in obj){
return false; // not empty
}
return true; // empty
}
No need for a library.
function(){ //must be within a function
var obj = {}; //the object to test
for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
return alert('not empty')//what ever you are trying to do once
return alert('empty'); //nope obj was empty do this instead;
}
It might be a bit hacky. You can try this.
if (JSON.stringify(data).length === 2) {
// Do something
}
Not sure if there is any disadvantage of this method.
fast onliner for 'dictionary'-objects:
function isEmptyDict(d){for (var k in d) return false; return true}
You can write a fallback if Array.isArray and Object.getOwnPropertyNames is not available
XX.isEmpty = function(a){
if(Array.isArray(a)){
return (a.length==0);
}
if(!a){
return true;
}
if(a instanceof Object){
if(a instanceof Date){
return false;
}
if(Object.getOwnPropertyNames(a).length == 0){
return true;
}
}
return false;
}
Imagine you have the objects below:
var obj1= {};
var obj2= {test: "test"};
Don't forget we can NOT use === sign for testing an object equality as they get inheritance, so If you using ECMA 5 and upper version of javascript, the answer is easy, you can use the function below:
function isEmpty(obj) {
//check if it's an Obj first
var isObj = obj !== null
&& typeof obj === 'object'
&& Object.prototype.toString.call(obj) === '[object Object]';
if (isObj) {
for (var o in obj) {
if (obj.hasOwnProperty(o)) {
return false;
break;
}
}
return true;
} else {
console.error("isEmpty function only accept an Object");
}
}
so the result as below:
isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object
funtion isEmpty(o,i)
{
for(i in o)
{
return!1
}
return!0
}
here's a good way to do it
function isEmpty(obj) {
if (Array.isArray(obj)) {
return obj.length === 0;
} else if (typeof obj === 'object') {
for (var i in obj) {
return false;
}
return true;
} else {
return !obj;
}
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isArray(a) {
return Object.prototype.toString.call(a) === '[object Array]'
}
function isObject(a) {
return Object.prototype.toString.call(a) === '[object Object]'
}
function isEmpty(a) {
if (null == a || "" == a)return!0;
if ("number" == typeof a || "string" == typeof a)return!1;
var b = !0;
if (isArray(a)) {
if (!a.length)return!0;
for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
return b
}
if (isObject(a)) {
for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
return b
}
return!0
}
May be you can use this decision:
var isEmpty = function(obj) {
for (var key in obj)
if(obj.hasOwnProperty(key))
return false;
return true;
}
I modified Sean Vieira's code to suit my needs. null and undefined don't count as object at all, and numbers, boolean values and empty strings return false.
'use strict';
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
var isObjectEmpty = function(obj) {
// null and undefined are not empty
if (obj == null) return false;
if(obj === false) return false;
if(obj === true) return false;
if(obj === "") return false;
if(typeof obj === "number") {
return false;
}
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
};
exports.isObjectEmpty = isObjectEmpty;
here my solution
function isEmpty(value) {
if(Object.prototype.toString.call(value) === '[object Array]') {
return value.length == 0;
} else if(value != null && typeof value === 'object') {
return Object.getOwnPropertyNames(value).length == 0;
} else {
return !(value || (value === 0));
}
}
Chears
if (Object.getOwnPropertyNames(obj1).length > 0)
{
alert('obj1 is empty!');
}

Categories