0

I have ruby background and am converting some ruby code to JavaScript.

I'm trying to understand the difference between hashes in ruby and JavaScript. I have a hash in ruby that looks like below:

main_hash = {"query" => { "filtered" => { "query"=> { "bool" => query_hash}}}}

I think the proper conversion for this in JavaScript would be basically a JSON like below:

var main_hash = {"query" : { "filtered" : { "query" : { "bool" : query_hash}}}}

But, I have some ruby logic that I'd like to replicate in JavaScript. And that code is:

if(query_hash.empty?)
  main_hash["query"]["filtered"].delete("query")
else
  main_hash["query"]["filtered"]["query"]["bool"] = query_hash
end

How do I access the nested attributes in JavaScript?

The reading I've been doing on w3schools indicates the below is the correct conversion, but I want to make sure I'm not missing any language semantics in this conversion. For example the delete only deletes the query object contained in filtered which is contained in query that is contained in main_hash correct?

 if(!isEmptyObject(query_hash)){
    delete main_hash.query.filtered.query;
 } else {
    main_hash.query.filtered.query.bool = query_hash;
 }
Gul Ershad
  • 1,743
  • 2
  • 25
  • 32
Horse Voice
  • 8,138
  • 15
  • 69
  • 120

2 Answers2

3

In JavaScript, your Ruby hash equivalent is an object. Properties of objects can be accessed two ways.

You can access them with the dot notation:

main_hash.query.filtered.query

Or using the array like access:

main_hash["query"]["filtered"]["query"]

Both work. And yes, the delete would only delete the innermost query property.

cal2u
  • 68
  • 4
AtheistP3ace
  • 9,611
  • 12
  • 43
  • 43
  • Thanks. What if `"query"` did not exist yet? could I just do this? `main_hash.query.filtered.query = {}` ? – Horse Voice Oct 09 '15 at 02:59
  • Yes. As long as filtered existed and was an object. That would initialize an empty object property inside filtered named query. – AtheistP3ace Oct 09 '15 at 10:50
  • @HorseVoice if this answered your question would you mind accepting it as an answer if its not too much trouble? Trying to earn points for privileges on site. Thanks! – AtheistP3ace Oct 09 '15 at 17:28
1

If you are using JQuery your code is ok, but if you are not, you need to create this isEmptyObject function.

You can use something like this function

function isEmpty(obj) {

    // Speed up calls to hasOwnProperty
    var hasOwnProperty = Object.prototype.hasOwnProperty;

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

    // 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([]), // 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
Community
  • 1
  • 1
Bruno João
  • 5,105
  • 2
  • 21
  • 26
  • Thank you. I have created the isEmptyObject method as such: `function isEmptyObject(obj){ return JSON.stringify(obj) === '{}'; },` Do you think this is okay, or does your solution offer more? I dI don't know where `var hasOwnProperty = Object.prototype.hasOwnProperty;` needs to be. I have an extjs class defined in which I'm doing this stuff. – Horse Voice Oct 08 '15 at 19:32
  • I've just edited my answer to help you position the hasOwnProperty variable. You can put it inside the function. – Bruno João Oct 09 '15 at 16:23
  • Not sure what exactly this is doing inside the method: `var hasOwnProperty = Object.prototype.hasOwnProperty;` What is `Object` here inside the method? – Horse Voice Oct 09 '15 at 19:08
  • It is a good parctice. If you need to use some object method more than once, is good to assign this method to a variable, so you do not need to call the object every time you need its method. The 'Object' is the Javascript object that expose native javascript methods. – Bruno João Oct 09 '15 at 19:22