使用jQuery';JSON对象上的s find()

使用jQuery';JSON对象上的s find(),jquery,jquery-selectors,Jquery,Jquery Selectors,类似于,我正在寻找一种通过类似JSON的对象进行搜索的方法。 假设我的对象的结构是这样的: TestObj = { "Categories": [{ "Products": [{ "id": "a01", "name": "Pine", "description": "Short description of pine." }, { "id":

类似于,我正在寻找一种通过类似JSON的对象进行搜索的方法。
假设我的对象的结构是这样的:

TestObj = {
    "Categories": [{
        "Products": [{
            "id": "a01",
            "name": "Pine",
            "description": "Short description of pine."
        },
        {
            "id": "a02",
            "name": "Birch",
            "description": "Short description of birch."
        },
        {
            "id": "a03",
            "name": "Poplar",
            "description": "Short description of poplar."
        }],
        "id": "A",
        "title": "Cheap",
        "description": "Short description of category A."
    },
    {
        "Product": [{
            "id": "b01",
            "name": "Maple",
            "description": "Short description of maple."
        },
        {
            "id": "b02",
            "name": "Oak",
            "description": "Short description of oak."
        },
        {
            "id": "b03",
            "name": "Bamboo",
            "description": "Short description of bamboo."
        }],
        "id": "B",
        "title": "Moderate",
        "description": "Short description of category B."
    }]
};
我想得到一个id为“A”的对象

我试过各种各样的东西,比如:

$(TestObj.find(":id='A'"))
但似乎什么都不管用


有人能想出一种不使用“each”而基于某些条件检索项的方法吗?

jQuery不适用于普通对象文本。您可以以类似的方式使用以下函数来搜索所有id(或任何其他属性),而不管其在对象中的深度如何:

function getObjects(obj, key, val) {
    var objects = [];
    for (var i in obj) {
        if (!obj.hasOwnProperty(i)) continue;
        if (typeof obj[i] == 'object') {
            objects = objects.concat(getObjects(obj[i], key, val));
        } else if (i == key && obj[key] == val) {
            objects.push(obj);
        }
    }
    return objects;
}
像这样使用:

getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects

纯javascript解决方案更好,但jQuery的方法是使用and/or方法。 可能不会比使用$更好

jQuery.grep(TestObj, function(obj) {
    return obj.id === "A";
});

返回匹配对象的数组,或者在map的情况下返回查找值的数组。只需使用这些工具,就可以做你想做的事情

但在本例中,您必须执行一些递归,因为数据不是平面数组,我们接受任意结构、键和值,就像纯javascript解决方案一样

function getObjects(obj, key, val) {
    var retv = [];

    if(jQuery.isPlainObject(obj))
    {
        if(obj[key] === val) // may want to add obj.hasOwnProperty(key) here.
            retv.push(obj);

        var objects = jQuery.grep(obj, function(elem) {
            return (jQuery.isArray(elem) || jQuery.isPlainObject(elem));
        });

        retv.concat(jQuery.map(objects, function(elem){
            return getObjects(elem, key, val);
        }));
    }

    return retv;
}
基本上与Box9的答案相同,但在有用的地方使用jQuery实用程序函数


········

我想提到的另一个选项是,您可以将数据转换为XML,然后使用
jQuery.find(“:id='A')”)
您想要的方式

有这样的jQuery插件,比如

可能不值得这样的转换开销,但这是静态数据的一次性成本,因此它可能很有用。

这对我来说在[{“id”:“data”},{“id”:“data”}上很有效


对于一维json,您可以使用:

function exist (json, modulid) {
    var ret = 0;
    $(json).each(function(index, data){
        if(data.modulId == modulid)
            ret++;
    })
    return ret > 0;
}
你可以用

这样做:

results = JSONPath(null, TestObj, "$..[?(@.id=='A')]")
请注意,JSONPath返回一个结果数组


(顺便说一句,我还没有测试表达式“$..[?(@.id='A')]”。可能需要借助浏览器控制台对其进行微调)

1。您有一个普通的JavaScript对象,而不是类似JSON的对象。您只需使用对象文字符号来定义它,JSON只是其中的一个子集(但JSON在完全不同的上下文中工作)。2.jQuery在DOM上工作,而不是在任意对象上工作。你用错了工具做这项工作。除了在产品数组上循环外,没有其他方法。它不是JSON对象。这也意味着你可以通过
for…in
循环数组,这是你应该避免的…@Felix,是的,你可以通过
for…in
循环数组,但是当给定任意对象时,不能保证其中的任何数组都是“真”数组。即使您检查构造函数、某些方法(如slice等),仍然可能存在expando属性,因此我不认为进一步定义逻辑有什么意义。@Box9:是的,可能不值得这样做。只是说这可能会导致意想不到的结果。但是通过
Object.prototype.toString.call(obj)
检测数组应该可以正常工作,这将给出
[Object Array]
@Felix,我想这取决于您希望数组的预期结果。即使数组是正常创建的(
[]
),您仍然可以向其添加(非数字)属性,这些属性可能是您想要或不想要迭代的。除此之外,检查
hasOwnProperty()
可以防止对原型中的属性进行迭代。@Box9:True。似乎我把重点放在了<代码>中的…和数组上,而我并没有真正意识到您正在使用
hasOwnProperty()
。。。没关系,我把一切都收回;)和+1作为赎回:o)我使用了这个
jQuery.grep(TestObj,function(obj){return obj.id==“A”})[0]
对于使用
$.grep()
的用户,请记住它返回一个数组。这意味着,如果您要查找单个项目,要访问它,您需要使用
$.grep(/*whatever*/)[0]
$.grep()刚刚帮我省去了一个可怕的巨大头痛。我的问题/解决方案与OP无关,但这只允许我查询数据库一次,而不是n次。好极了@davepncj如果我比较字符串,那么字符串有一些区别,一个字母在对象中是小的,一个字母在比较的字符串中是大写的。那么我们如何才能消除这种差异(小写和大写字母)
function exist (json, modulid) {
    var ret = 0;
    $(json).each(function(index, data){
        if(data.modulId == modulid)
            ret++;
    })
    return ret > 0;
}
results = JSONPath(null, TestObj, "$..[?(@.id=='A')]")