如何在嵌套对象中搜索特定文本?

时间:2013-05-01 02:39:39

标签: javascript json

例如,我有一个JSON数组如下,我将在一个树形图上显示它,以便用户可以选择该项目。现在有一个功能允许用户搜索列表中的特定文本。列表是一个嵌套列表。我使用HTML和Javascript将JSON数组绑定到树状列表。现在我应该找到一种搜索特定文本的好方法,然后在找到文本时返回包含父节点的对象。

var allcategories=
[
{
    "name": "shoes",
    "subcategories": [
        {
            "name": "man's shoes",
            "subcategories": [
                {
                    "name": "sample name"
                },
                {
                    "name": "sample name",
                    "subcategories": []
                }
            ]
        },
        {
            "name": "woman's shoes",
            "subcategories": []
        }
    ]
},
{
    "name": "cars",
    "subcategories": [
        {
            "name": "cars1",
            "subcategories": [
                {
                    "name": "sample name"
                },
                {
                    "name": "sample name",
                    "subcategories": []
                }
            ]
        }
    ]
}
];

所以现在我想使用indexOf()函数来搜索结果。如果搜索成功,程序应该只返回父类别。任何人在开发代码时都有相同的问题?

3 个答案:

答案 0 :(得分:1)

正如Bergi建议的那样,你可以使用递归函数:

  function getCategory(categories, name) {
    var category, result;

    for (var i=0, iLen=categories.length; i<iLen; i++) {
      category = categories[i];

      if (category.name == name) {
        return category;

      } else if (category.subcategories) {
        result = getCategory(category.subcategories, name);

        if (result) return result;
      }
    }
    // return undefined if category name not found
  }

请注意,这将返回具有匹配名称的第一个子类别,因此名称必须是唯一的。

答案 1 :(得分:0)

@Leeli - 你可以使用这个JS lib;使用JSON结构进行搜索的DefiantJS(http://defiantjs.com)变得微不足道。 lib使用“search”方法扩展全局对象JSON。使用此方法,您可以使用XPath表达式进行搜索,它将使用匹配重新调整数组(如果未找到匹配项,则返回空数组)。请参阅下面的示例代码。

这是一个工作小提琴:
http://jsfiddle.net/hbi99/wXfE6/

var data = [
       {
          "name": "shoes",
          "subcategories": [
             {
                "name": "man's shoes",
                "subcategories": [
                   { "name": "heels" },
                   { "name": "loafers" }
                ]
             },
             { "name": "woman's shoes" }
          ]
       },
       {
          "name": "cars",
          "subcategories": {
             "name": "cars1",
             "subcategories": [
                { "name": "Sedan" },
                { "name": "SUV" }
             ]
          }
       }
    ],
    res = JSON.search( data, '//*[name="cars1"]/subcategories' );

console.log( res[0].name );
// Sedan

答案 2 :(得分:0)

这里是我写的一个jquery函数。由于它是.net中的一个关联列表,当没有子节点时,子列表是一个空对象,所以我必须检查是空的而不是简单地查找它为空。应该是向后兼容的,并作为这个问题的解决方案

function findCategory(categories, categoryId)
    {
        var ret = null;
        $.each(categories, function (e, v) {
            if (e === categoryId)
                ret = v;
            else if (!jQuery.isEmptyObject(v.children))
                ret = findCategory(v.children, categoryId);
            return !ret; //break out of loop when ret not null
        });
        return ret;
    }