9

I've got the following JSON string:

{
   "Alarm":{
      "Hello":48,
      "World":3,
      "Orange":1
   },
   "Rapid":{
      "Total":746084,
      "Fake":20970,
      "Cancel":9985,
      "Word": 2343
   },
   "Flow":{
      "Support":746084,
      "About":0,
      "Learn":0
   }
}

Then I load the above string and convert it to json object:

jsonStr = '{"Alarm":{"Hello":48,"World":3,"Orange":1},"Rapid":{"Total":746084,"Fake":20970,"Cancel":9985},"Flow":{"Support":746084,"About":0,"Learn":0}}';
var jsonObj = JSON.parse(jsonStr);

Now, how can I filter this json object by key name?

E.g., if the filter was "ange", the filtered object would be:

{
   "Alarm":{
      "Orange":1
   }
}

If the filter was "flo", the filtered object would become:

{
   "Flow":{
      "Support":746084,
      "About":0,
      "Learn":0
   }
}

And if the filter was "wor", the result would be:

{
   "Alarm":{
      "World": 3,
   },
   "Rapid":{
      "Word": 2343
   }
}

Is it possible to achieve this filtering using the filter method?

8
  • 1
    Possible duplicate of Filtering JSON data Commented Sep 17, 2016 at 11:11
  • There's no such thing as a "JSON object" – JSON is always a string; nothing more. Commented Apr 29, 2017 at 17:36
  • @naomik You mean JSON.parse(jsonStr) returns a string? Commented Apr 29, 2017 at 18:19
  • @Meysam, no. JSON.stringify(data) returns a string. JSON.parse(json) returns the parsed data. think of JSON as "javascript data in a JSON-formatted string". When you say "JSON object" you most likely mean a "JavaScript object" Commented Apr 29, 2017 at 19:02
  • @naomik From documentation: Parse the data with JSON.parse(), and the data becomes a JavaScript object. Commented Apr 29, 2017 at 19:10

3 Answers 3

22

Beside the given solutions, you could use a recursive style to check the keys.

This proposal gives the opportunity to have more nested objects inside and get only the filtered parts.

function filterBy(val) {
    function iter(o, r) {
        return Object.keys(o).reduce(function (b, k) {
            var temp = {};
            if (k.toLowerCase().indexOf(val.toLowerCase()) !== -1) {
                r[k] = o[k];
                return true;
            }
            if (o[k] !== null && typeof o[k] === 'object' && iter(o[k], temp)) {
                r[k] = temp;
                return true;
            }
            return b;
        }, false);
    }

    var result = {};
    iter(obj, result);
    return result;
}

var obj = { Alarm: { Hello: 48, "World": 3, Orange: 1 }, Rapid: { Total: 746084, Fake: 20970, Cancel: 9985, Word: 2343 }, Flow: { Support: 746084, About: 0, Learn: 0 }, test: { test1: { test2: { world: 42 } } } };

console.log(filterBy('ange'));
console.log(filterBy('flo'));
console.log(filterBy('wor'));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

Comments

9

You can create a function using reduce() and Object.keys() that will check key names with indexOf() and return the desired result.

var obj = {
  "Alarm": {
    "Hello": 48,
    "World": 3,
    "Orange": 1
  },
  "Rapid": {
    "Total": 746084,
    "Fake": 20970,
    "Cancel": 9985,
    "Word": 2343
  },
  "Flow": {
    "Support": 746084,
    "About": 0,
    "Learn": 0
  }
}

function filterBy(val) {
  var result = Object.keys(obj).reduce(function(r, e) {
    if (e.toLowerCase().indexOf(val) != -1) {
      r[e] = obj[e];
    } else {
      Object.keys(obj[e]).forEach(function(k) {
        if (k.toLowerCase().indexOf(val) != -1) {
          var object = {}
          object[k] = obj[e][k];
          r[e] = object;
        }
      })
    }
    return r;
  }, {})
  return result;
}

console.log(filterBy('ange'))
console.log(filterBy('flo'))
console.log(filterBy('wor'))

1 Comment

Hi, there is a bug in your code I couldn't get fixed. Could you please take a look at it? jsfiddle.net/1tmwkkza/2 In the sample code if you search for is, only IsHello is returned and IsWorld is ignored.
3

With the filter method I think you mean the Array#filter function. This doesn't work for objects.

Anyway, a solution for your input data could look like this:

function filterObjects(objects, filter) {
    filter = filter.toLowerCase();
    var filtered = {};
    var keys = Object.keys(objects);
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        if (objects.hasOwnProperty(key) === true) {
            var object = objects[key];
            var objectAsString = JSON.stringify(object).toLowerCase();
            if (key.toLowerCase().indexOf(filter) > -1 || objectAsString.indexOf(filter) > -1) {
                filtered[key] = object;
            }
        }
    }
    return filtered;
}

1 Comment

you may skip the === true in if (objects.hasOwnProperty(key) === true).

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.