2

I am trying to create a recursive function that filters an object, depending on the properties in the second passed argument.

Filtering works well, but my arrays are being replaced with empty objects. What could I do different so that this doesn’t occur?

var filter = function(obj, fields) {
  var key, o;

  if (typeof obj !== "object") { return obj;}
  o = {};
  for (key in obj) {
    if (fields[key]) {
      o[key] = filter(obj[key], fields[key]);
    }
  }
  return o;
};


data = {name: "John Doe", followers: [], notAllowedProp: false}
allowedFields = {name: true, followers: true}

console.log(filter(data, allowedFields));
// => Object { name: "John Doe", followers: {}}
1
  • you are returning an empty object regardless of the fields type I suggest checking the filed type and initiating o by it. Commented Oct 16, 2012 at 17:11

2 Answers 2

1

Try this on a console:

> typeof []
"object"

To check for an array more robustly, you can use Object.prototype.toString:

> Object.prototype.toString.call([])
"[object Array]"

Object.prototype.toString has well-defined behavior for all native objects, and is quite reliable. Thus, for example, if you want to return anything that is not a "true" object, you could write:

if (Object.prototype.toString(obj) !== "[object Object]") {
    return obj;
}
Sign up to request clarification or add additional context in comments.

10 Comments

Or [].constructor === Array.
Although they work, there are certain problems that can arise with those techniques that don't occur if you use Object.prototype.toString.
@voithos If you're not using iframes that interact with each other programmatically, you're fine using instanceof.
@PeterOlson: Sure, but that scenario is a plus for using Object.prototype.toString regardless. And from another standpoint, I'd argue that Object.prototype.toString is more readable than manipulating typeof and instanceof.
@pebbl: Yes, what you're speaking of is duck typing, which is fine in most cases.
|
1

Arrays have type object. Consequently, you'll need to edit this line if you want to return early for arrays:

if (typeof obj !== "object") { return obj; } 

There are many ways to check for an array, but this is what I would do:

if(typeof obj !== "object" && !(obj instanceof Array)) { return obj; } 

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.