Javascript search inside a JSON object

JavascriptJqueryJsonpJson

Javascript Problem Overview


I had a JSON string / object in my application.

{"list": [
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]}

I had a filter box in my application, and when I type a name into that box, we have to filter the object and display the result.

For example, if the user types "name" and hits search, then we have to search full names in the JSON object and return the array, just like a MySQL search ...

My question is to filter the json object with string and return the array....

Javascript Solutions


Solution 1 - Javascript

You could just loop through the array and find the matches:

var results = [];
var searchField = "name";
var searchVal = "my Name";
for (var i=0 ; i < obj.list.length ; i++)
{
    if (obj.list[i][searchField] == searchVal) {
        results.push(obj.list[i]);
    }
}

Solution 2 - Javascript

If your question is, is there some built-in thing that will do the search for you, then no, there isn't. You basically loop through the array using either String#indexOf or a regular expression to test the strings.

For the loop, you have at least three choices:

  1. A boring old for loop.

  2. On ES5-enabled environments (or with a shim), Array#filter.

  3. Because you're using jQuery, jQuery.map.

Boring old for loop example:

function search(source, name) {
    var results = [];
    var index;
    var entry;

    name = name.toUpperCase();
    for (index = 0; index < source.length; ++index) {
        entry = source[index];
        if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {
            results.push(entry);
        }
    }

    return results;
}

Where you'd call that with obj.list as source and the desired name fragment as name.

Or if there's any chance there are blank entries or entries without names, change the if to:

        if (entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1) {

Array#filter example:

function search(source, name) {
    var results;

    name = name.toUpperCase();
    results = source.filter(function(entry) {
        return entry.name.toUpperCase().indexOf(name) !== -1;
    });
    return results;
}

And again, if any chance that there are blank entries (e.g., undefined, as opposed to missing; filter will skip missing entries), change the inner return to:

        return entry && entry.name && entry.name.toUpperCase().indexOf(name) !== -1;

jQuery.map example (here I'm assuming jQuery = $ as is usually the case; change $ to jQuery if you're using noConflict):

function search(source, name) {
    var results;

    name = name.toUpperCase();
    results = $.map(source, function(entry) {
        var match = entry.name.toUpperCase().indexOf(name) !== -1;
        return match ? entry : null;
    });
    return results;
}

(And again, add entry && entry.name && in there if necessary.)

Solution 3 - Javascript

You can simply save your data in a variable and use find(to get single object of records) or filter(to get single array of records) method of JavaScript.

For example :-

let data = {
 "list": [
   {"name":"my Name","id":12,"type":"car owner"},
   {"name":"my Name2","id":13,"type":"car owner2"},
   {"name":"my Name4","id":14,"type":"car owner3"},
   {"name":"my Name4","id":15,"type":"car owner5"}
]}

and now use below command onkeyup or enter

to get single object

data.list.find( record => record.name === "my Name")

to get single array object

data.list.filter( record => record.name === "my Name")

Solution 4 - Javascript

Use PaulGuo's jSQL, a SQL like database using javascript. For example:

var db = new jSQL();
db.create('dbname', testListData).use('dbname');
var data = db.select('*').where(function(o) {
	return o.name == 'Jacking';
}).listAll();

Solution 5 - Javascript

I adapted regex to work with JSON.

First, stringify the JSON object. Then, you need to store the starts and lengths of the matched substrings. For example:

"matched".search("ch") // yields 3

For a JSON string, this works exactly the same (unless you are searching explicitly for commas and curly brackets in which case I'd recommend some prior transform of your JSON object before performing regex (i.e. think :, {, }).

Next, you need to reconstruct the JSON object. The algorithm I authored does this by detecting JSON syntax by recursively going backwards from the match index. For instance, the pseudo code might look as follows:

find the next key preceding the match index, call this theKey
then find the number of all occurrences of this key preceding theKey, call this theNumber
using the number of occurrences of all keys with same name as theKey up to position of theKey, traverse the object until keys named theKey has been discovered theNumber times
return this object called parentChain

With this information, it is possible to use regex to filter a JSON object to return the key, the value, and the parent object chain.

You can see the library and code I authored at http://json.spiritway.co/

Solution 6 - Javascript

If you are doing this in more than one place in your application it would make sense to use a client-side JSON database because creating custom search functions that get called by array.filter() is messy and less maintainable than the alternative.

Check out ForerunnerDB which provides you with a very powerful client-side JSON database system and includes a very simple query language to help you do exactly what you are looking for:

// Create a new instance of ForerunnerDB and then ask for a database
var fdb = new ForerunnerDB(),
    db = fdb.db('myTestDatabase'),
    coll;

// Create our new collection (like a MySQL table) and change the default
// primary key from "_id" to "id"
coll = db.collection('myCollection', {primaryKey: 'id'});

// Insert our records into the collection
coll.insert([
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]);

// Search the collection for the string "my nam" as a case insensitive
// regular expression - this search will match all records because every
// name field has the text "my Nam" in it
var searchResultArray = coll.find({
    name: /my nam/i
});

console.log(searchResultArray);

/* Outputs
[
    {"name":"my Name","id":12,"type":"car owner"},
    {"name":"my Name2","id":13,"type":"car owner2"},
    {"name":"my Name4","id":14,"type":"car owner3"},
    {"name":"my Name4","id":15,"type":"car owner5"}
]
*/

Disclaimer: I am the developer of ForerunnerDB.

Solution 7 - Javascript

Here is an iterative solution using object-scan. The advantage is that you can easily do other processing in the filter function and specify the paths in a more readable format. There is a trade-off in introducing a dependency though, so it really depends on your use case.

// const objectScan = require('object-scan');

const search = (haystack, k, v) => objectScan([`list[*].${k}`], {
  rtn: 'parent',
  filterFn: ({ value }) => value === v
})(haystack);

const obj = { list: [ { name: 'my Name', id: 12, type: 'car owner' }, { name: 'my Name2', id: 13, type: 'car owner2' }, { name: 'my Name4', id: 14, type: 'car owner3' }, { name: 'my Name4', id: 15, type: 'car owner5' } ] };

console.log(search(obj, 'name', 'my Name'));
// => [ { name: 'my Name', id: 12, type: 'car owner' } ]

<script src="https://bundle.run/[email protected]"></script>

.as-console-wrapper {max-height: 100% !important; top: 0}

Disclaimer: I'm the author of object-scan

Solution 8 - Javascript

You can try this:

function search(data,search) {
    var obj = [], index=0;
    for(var i=0; i<data.length; i++) {
      for(key in data[i]){
         if(data[i][key].toString().toLowerCase().indexOf(search.toLowerCase())!=-1) {
                obj[index] = data[i];
                index++;
                break;
         }
     }
     return obj;
}
console.log(search(obj.list,'my Name'));

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionrameshView Question on Stackoverflow
Solution 1 - JavascriptMcGarnagleView Answer on Stackoverflow
Solution 2 - JavascriptT.J. CrowderView Answer on Stackoverflow
Solution 3 - JavascriptAnand Deep SinghView Answer on Stackoverflow
Solution 4 - JavascriptJackingLiuView Answer on Stackoverflow
Solution 5 - JavascriptmikewhitView Answer on Stackoverflow
Solution 6 - JavascriptRob EvansView Answer on Stackoverflow
Solution 7 - JavascriptvincentView Answer on Stackoverflow
Solution 8 - JavascriptMengtyView Answer on Stackoverflow