在 JSON 对象中进行 JavaScript 搜索

问题描述 投票:0回答:9

我的应用程序中有一个 JSON 字符串/对象。

{"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"}
]}

我的应用程序中有一个过滤框,当我在该框中输入名称时,我们必须过滤对象并显示结果。

例如,如果用户输入“name”并点击搜索,那么我们必须在 JSON 对象中搜索全名并返回数组,就像 MySQL 搜索一样......

我的问题是如何通过指定的字符串过滤json对象并返回数组....

javascript jquery jsonp json
9个回答
61
投票

您可以循环遍历数组并找到匹配项:

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

48
投票

如果您的问题是,是否有一些内置的东西可以为您进行搜索,那么不,没有。您基本上使用

String#indexOf
正则表达式 循环遍历数组来测试字符串。

对于循环,您至少有三个选择:

  1. 一个无聊的旧

    for
    循环。

  2. 在启用 ES5 的环境中(或使用填充程序),

    Array#filter

  3. 因为您使用的是 jQuery,

    jQuery.map

无聊的旧

for
循环示例:

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

您可以将其称为

obj.list
source
并将所需的名称片段称为
name

或者,如果可能存在空白条目或没有名称的条目,请将

if
更改为:

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

Array#filter
示例:

function search(source, name) {
    var results;

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

再次,如果有可能存在空白条目(例如,

undefined
,而不是缺失;
filter
将跳过缺失条目),请将内部返回更改为:

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

jQuery.map
示例(这里我假设
jQuery
=
$
,通常情况如此;如果您使用
$
,请将
jQuery
更改为
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;
}

(如有必要,再次添加

entry && entry.name &&
。)


20
投票

您可以简单地将数据保存在变量中,然后使用 JavaScript 的 find(获取单个记录对象)或 filter(获取单个记录数组)方法。

例如:-

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"}
]}

现在使用下面的命令 onkeyup 或 Enter

获取单个对象

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

获取单个数组对象

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

2
投票

使用PaulGuojSQL,一个使用javascript的类似SQL的数据库。例如:

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

2
投票

我调整了正则表达式以使用 JSON。

首先,对 JSON 对象进行字符串化。 然后,您需要存储匹配子字符串的开头和长度。 例如:

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

对于 JSON 字符串,其工作原理完全相同(除非您显式搜索逗号和大括号,在这种情况下,我建议在执行正则表达式之前对 JSON 对象进行一些预先转换(即认为 :, {, })。

接下来,您需要重建 JSON 对象。 我编写的算法通过从匹配索引递归向后检测 JSON 语法来实现此目的。 例如,伪代码可能如下所示:

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

有了这些信息,就可以使用正则表达式来过滤 JSON 对象以返回键、值和父对象链。

您可以在http://json.spiritway.co/

查看我编写的库和代码

1
投票

如果您在应用程序中的多个位置执行此操作,那么使用客户端 JSON 数据库是有意义的,因为创建由 array.filter() 调用的自定义搜索函数会很混乱,并且比其他方法更难维护。

查看 ForerunnerDB,它为您提供了一个非常强大的客户端 JSON 数据库系统,并包含一个非常简单的查询语言,可以帮助您准确地完成您想要的操作:

// 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"}
]
*/

免责声明:我是 ForerunnerDB 的开发者。


0
投票

这是使用对象扫描的迭代解决方案。优点是您可以轻松地在过滤器函数中进行其他处理,并以更易读的格式指定路径。不过,引入依赖项需要权衡,因此这实际上取决于您的用例。

// 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' } ]
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

免责声明:我是object-scan

的作者

0
投票

您可以使用此库使用任何属性中的任何值来过滤 json 对象 Js-搜索


-2
投票

你可以试试这个:

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'));
© www.soinside.com 2019 - 2024. All rights reserved.