如何将JSON作为路径进行搜索

时间:2014-07-15 14:59:53

标签: javascript json

我有一个JSON,如下所示

{
    "name": "Soft Drinks",
    "T2": [
        {
            "name": "Bottled",
            "T3": [
                {
                    "name": "Apple",
                    "leaf": [
                        {
                            "name": "Apple 500 ML"
                        },
                        {
                            "name": "Apple 1 Ltr"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Fountain",
            "T3": [
                {
                    "name": "Apple",
                    "leaf": [
                        {
                            "name": "Apple Regular, 500 ML"
                        }
                    ]
                }
            ]
        },
        {
            "name": "Tin",
            "T3": [
                {
                    "name": "Apple",
                    "leaf": [
                        {
                            "name": "Apple Regular, 300 ML"
                        }
                    ]
                }
            ]
        }
    ]
}

我将得到一个输入字符串,因为Path意味着这样一个数组

第一案:

输入Soft Drinks,Bottled

输出["Apple"]

第二案:

输入Soft Drinks,Fountain,Apple

输出

[
    "leaf",
    [
        {
           "name": "Apple Regular, 500 ML"
        }
    ]
]

有人可以帮我解决这个问题吗? 我在通过Jquery Accordian导航时形成了这个输入数组,所以根据点击,我需要显示相应的数据。

供您参考,屏幕看起来像这样

enter image description here

enter image description here

1 个答案:

答案 0 :(得分:1)

一些更改:每个节点都有名称 leaf 键,

var drinks = [
  {
    "name": "Soft Drinks",
    "leaf": [
      {
        "name": "Bottled",
        "leaf": [
          {
            "name": "Apple",
            "leaf": [
              {
                "name": "Apple 500 ML"
              },
              {
                "name": "Apple 1 Ltr"
              }
            ]
          }
        ]
      },
      {
        "name": "Fountain",
        "leaf": [
          {
            "name": "Apple",
            "leaf": [
              {
                "name": "Apple Regular, 500 ML"
              }
            ]
          }
        ]
      },
      {
        "name": "Tin",
        "leaf": [
          {
            "name": "Apple",
            "leaf": [
              {
                "name": "Apple Regular, 300 ML"
              }
            ]
          }
        ]
      }
    ]
  }
];

var drinkParser = (function () {

  function DrinksCollection(nodes) {
    extend(this, nodes);
    this.length = nodes.length;
    this.parent = null;
  }

  /*
   * Method extend from Underscore.js 1.6.0
   * http://underscorejs.org
   * (c) 2009-2014 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
   * Underscore may be freely distributed under the MIT license.
   */
  function extend(obj) {
    Array.prototype.slice.call(arguments, 1).forEach(function (source) {
      if (source) {
        for (var prop in source) {
          obj[prop] = source[prop];
        }
      }
    });
    return obj;
  }

  function nodeMatcher(node, selectorExpr) {
    var type = typeof selectorExpr;
    if (type === "string") {
      return node.name === selectorExpr;
    } else if (type === "function") {
      return !!selectorExpr(node);
    } else {
      throw new TypeError("Cannot filter node with selector " + selectorExpr);
    }
  }

  DrinksCollection.prototype = {
    toArray: function () {
      return Array.prototype.slice.call(this);
    },

    find: function (selectorExpr) {
      var foundNodes = [];
      this.walk(function (node) {
        if (nodeMatcher(node, selectorExpr)) {
          foundNodes.push(node);
        }
      });
      return this.pushStack(foundNodes);
    },

    each: function (callback) {
      this.toArray().forEach(callback);
      return this;
    },

    map: function (callback) {
      return this.toArray().map(callback);
    },

    walk: function (callback) {
      function walk(node, index) {
        callback.call(node, node, index);
        (node.leaf || []).forEach(walk);
      }

      this.each(walk);
      return this;
    },

    pushStack: function (nodes) {
      var newInstance = new DrinksCollection(nodes);
      newInstance.parent = this;
      return newInstance;
    },

    children: function () {
      var allChildren = [];
      this.each(function (node) {
        allChildren = allChildren.concat(node.leaf);
      });
      return this.pushStack(allChildren);
    },

    props: function (propName) {
      return this.map(function (node) {
        return node[propName];
      });
    },

    names: function () {
      return this.props("name");
    }

  };

  return function (nodes) {
    return new DrinksCollection(nodes);
  }
}());

(function parseDrinks() {
  console.log(drinkParser(drinks).find('Soft Drinks').find('Bottled').children().names()); // [ 'Apple' ]
  console.log(drinkParser(drinks).find('Soft Drinks').find('Bottled').find('Apple').children().map(function (drink) {
    return drink;
  })); // [ { name: 'Apple 500 ML' }, { name: 'Apple 1 Ltr' } ]
}());