varad
varad

Reputation: 8029

javascript check if dictionary

I have a simple program like:

var a = {'a': 1, 'b': 2}
console.log(a)
console.log(a instanceof Array)
console.log(a.constructor instanceof Array)

Here the value of a is a dictionary. I want to check for it.

How can I check it in javascript? Both tests above give me false result.

Upvotes: 35

Views: 75285

Answers (9)

kofifus
kofifus

Reputation: 19305

To test for plain dictionary use
v !== undefined && v !== null && v.constructor == Object

Here is a test on all JavaScript data types and data structures:

const isDict = v => v !== undefined && v !== null && v.constructor == Object

let test = [ undefined, null, {}, { x: 5}, true, 5, 10n, "x", Symbol(), isDict, new Date(), [1], new Array(), new Uint8Array(), new Uint16Array(), new Uint32Array(), new Float64Array(),  new ArrayBuffer(), new DataView(new ArrayBuffer()), new Set(), new WeakSet(), new Map(), new WeakMap() ]

test.forEach(v => { if (isDict(v)) console.log(JSON.stringify(v)) })

Upvotes: 9

FrameMuse
FrameMuse

Reputation: 373

I know this is a question about JavaScript but here's the TypeScript version of the @Floyd answer

Typescript version

function isRecord(object: unknown): object is Record<keyof never, unknown> {
  return object instanceof Object && object.constructor === Object
}

@Floyd's answer

if (a.constructor == Object) {
    // code here...
}

Upvotes: 2

Sohail Si
Sohail Si

Reputation: 2976

An inefficient but more rigorous way is to use JSON (This will exclude other classes and "associative arrays" from being counted as 'object'). Note that it is not a performance & memory -efficient solution. This is can only be recommended for test purposed:

function isDict(v) {
    return !!v && typeof v==='object' && v!==null && !(v instanceof Array) && !(v instanceof Date) && isJsonable(v);
}

function isJsonable(v) {
    try{
        return JSON.stringify(v) === JSON.stringify(JSON.parse(JSON.stringify(v)));
     } catch(e){
        /*console.error("not a dict",e);*/
        return false;
    }
}

Upvotes: 1

jfriend00
jfriend00

Reputation: 707876

The structure {'a': 1, 'b': 2} is a Javascript object. It can be used sort of like a dictionary, but a Map object is closer to what most people think of as a dictionary.

console.log(typeof a);            // "object"
console.log(Array.isArray(a));    // false, because it's not an array

If you want to know if something is an array, then use:

Array.isArray(a)

If you want to know if something is an object, then use:

typeof a === "object"

But, you will have to be careful because an Array is an object too.


If you want to know if something is a plain object, you can look at what jQuery does to detect a plain object:

isPlainObject: function( obj ) {
    // Not plain objects:
    // - Any object or value whose internal [[Class]] property is not "[object Object]"
    // - DOM nodes
    // - window
    if ( jQuery.type( obj ) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
        return false;
    }

    // Support: Firefox <20
    // The try/catch suppresses exceptions thrown when attempting to access
    // the "constructor" property of certain host objects, ie. |window.location|
    // https://bugzilla.mozilla.org/show_bug.cgi?id=814622
    try {
        if ( obj.constructor &&
                !hasOwn.call( obj.constructor.prototype, "isPrototypeOf" ) ) {
            return false;
        }
    } catch ( e ) {
        return false;
    }

    // If the function hasn't returned already, we're confident that
    // |obj| is a plain object, created by {} or constructed with new Object
    return true;
},

Upvotes: 7

Tanner Dolby
Tanner Dolby

Reputation: 4431

In JavaScript, an Object is created using curly braces e.g. {'foo': 'bar'} (literal notation) or with the constructor new Object(). The term "dictionary" is used when discussing Python code and "object" when discussing JS code. Building on that, in Python we would use isinstance({'foo': 'bar'}, dict) to determine if some data point is a dictionary data type.

The equivalent check in JavaScript will utilize the fact that any "object" which is initialized from the Object() constructor or literal notation will be an instanceof the Object class and make use of the Object() constructor. Therefore, we can always verify that foo.constructor == Object is true for {} or new Object(). That tells us the data type is specifically object and not an array.

const obj = { foo: "bar" };
console.log(obj instanceof Object); // true
console.log(obj.constructor == Object); // true

const objTwo = new Object();
console.log(objTwo.constructor == Object); // true

const arr = [1,2,3];
console.log(arr instanceof Array); // true
console.log(arr.constructor == Array); // true
console.log(arr instanceof Object); // true
console.log(arr.constructor == Object); // false

JavaScript defines arrays as predefined objects, where the indexes are the arrays properties. So although [1,2] instanceof Object is true, it will still be false for [1,2].constructor == Object. This is because the "array" is an object of the Array class which utilizes the Array() constructor and not the Object() constructor. This can cause some confusion, but remember when trying to determine if something is an "object" (dictionary for those with a Python background), checking the underlying constructor being used for object creation will quickly determine if your dealing with an "object" {} or an "array" [].

Upvotes: 1

Pavan Varyani
Pavan Varyani

Reputation: 1526

I use the toString method in Object.prototype, This works like a charm in all the cases(Array,null,undefined etc).

var array_var=[1,2];
var dict_var={
'a':'hey',
'b':'hello'
};
console.log(Object.prototype.toString.call(dict_var) === '[object Object]');//returns true
console.log(Object.prototype.toString.call(array_var) === '[object Object]');//returns false  

In short the toString method is used to represent the object, for example the toString method for an array returns '[object Array]'

Upvotes: 0

David Alvarez
David Alvarez

Reputation: 1286

Would that work ?

function isDictObj(obj: any) {
  try {
    const test = {...obj}
  } catch(err) {
    return false
  }
  return true
}

My logic is that if it is a dictionnary object (key:values), then using spread operator with {} should work, otherwise throw an exception

Upvotes: -2

Jagannath Swarnkar
Jagannath Swarnkar

Reputation: 369

You can use this to check either your dict(data) is a dictionary or not !

var dict = { a: 1, b: { c: 3, d: 4 }, e: 9 };

// this function will true / false

const isDict = dict => {
  return typeof dict === "object" && !Array.isArray(dict);
};

console.log(isDict(dict));  // true

this will return you true if it is a dictionary otherwise return false

Upvotes: 1

Floyd
Floyd

Reputation: 2452

The simplest approach to check if something is a dictionary in Javascript in a way that will not also return true when given an array is:

if (a.constructor == Object) {
    // code here...
}

This was inspired by the answer here.

Upvotes: 62

Related Questions