How can I filter a JSON object in JavaScript?

20,259

Solution 1

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'))

Solution 2

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

Solution 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;
}
Share:
20,259
B Faley
Author by

B Faley

Updated on July 26, 2020

Comments

  • B Faley
    B Faley almost 4 years

    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?