使用 underscore.js 在深度嵌套的 JSON 中查找值

Using underscore.js to find values in deeply nested JSON

我是 Javascript 的新手,我刚刚了解 underscore.js。我有一个深度嵌套的 JSON 对象,我需要使用下划线来查找 key/value 对,然后我将使用它来填充各种 HTML table。如果结构更浅,使用 _.pluck 之类的东西会很容易,但我只是不知道如何遍历前几个嵌套级别(即 surveyGDB、table、table名字)。 JSON 对象来自一个 XML,它由多个嵌套结构组成(来自不同的数据库 table)。

var JSONData = 
"surveyGDB": {
      "filename": "..\Topo\SurveyGeoDatabase.gdb",
      "table": {
        "tablename": [
          {
            "#text": "SurveyInfo\n      ",
            "record": {
              "OBJECTID": "1",
              "SiteID": "CBW05583-345970",
              "Watershed": "John Day",
              "VisitType": "Initial visit",
              "SurveyInstrument": "Total Station",
              "ImportDate": "2015-07-22T09:08:42",
              "StreamName": "Duncan Creek",
              "InstrumentModel": "TopCon Magnet v2.5.1",
              "FieldSeason": "2015"
          }
        },
        {
          "#text": "QaQcPoints\n      ",
          "record": [
            {
              "OBJECTID": "1",
              "TIMESTAMP": "2015-07-22T09:18:43",
              "Code": "tp",
              "Count": "357"
            },
            {
              "OBJECTID": "2",
              "TIMESTAMP": "2015-07-22T09:18:43",
              "Code": "tb",
              "Count": "92"
            },
            {
              "OBJECTID": "3",
              "TIMESTAMP": "2015-07-22T09:18:43",
              "Code": "to",
              "Count": "8"
            },
            {
              "OBJECTID": "4",
              "TIMESTAMP": "2015-07-22T09:18:43",
              "Code": "bl",
              "Count": "279"
            },
            {
              "OBJECTID": "5",
              "TIMESTAMP": "2015-07-22T09:18:43",
              "Code": "bf",
              "Count": "18"
            }
          ]
        },
        {
          "#text": "QaQcPolygons\n      ",
          "record": [
            {
              "OBJECTID": "1",
              "TIMESTAMP": "2015-07-22T09:43:08",
              "SurveyExtentCount": "",
              "WaterExtentCount": "",
              "ChannelUnitsCount": "",
              "ChannelUnitsUnique": ""
            },
            {
              "OBJECTID": "2",
              "TIMESTAMP": "2015-07-22T13:35:15",
              "SurveyExtentCount": "1",
              "WaterExtentCount": "1",
              "ChannelUnitsCount": "21",
              "ChannelUnitsUnique": "21"
            }
          ]
        }
      ]
    }
  }
}

例如,我想要 'QaQCPoints' table 中 'Code' 的所有值,所以我尝试了:

var codes = _.flatten(_.pluck(JSONData.surveyGDB.table.tablename[1].record[0], "Code" ));
console.log(codes);

在控制台中,这个 returns 一个长度为 5 的数组,但包含空白值。 我做错了什么?

我还宁愿根据“#text”键值之类的东西在 table 中搜索 'Code' 值,而不是仅仅使用它在对象中的位置。

如果我对您的理解正确,您希望始终在 JSONData.surveyGDB.table.tablename 数组中搜索 record 数组以获取某些查询。这意味着您需要根据某些参数和 return 找到的记录中的某些内容来查找记录。

请注意,在您的示例中,record 属性 有时是一个数组,有时是一个对象(对于 table SurveyInfo),所以我假设您需要考虑到这一点。 您可以制作一个小函数来提取数据并同时处理对象和数组:

function extract(record, prop) {
  if (Array.isArray(record)) { 
    return _.pluck(record, prop);
  } else {
    return record[prop];
  }
}

用法示例:

I wanted all of the values for 'Code' in the 'QaQCPoints' table. I'd also rather search for the 'Code' values in the table based on something like the '#text' key value, instead of just using it's position in the object.

为此,您首先使用 _.find 查找记录,然后使用上述方法从中提取 Code 值:

var table = JSONData.surveyGDB.table.tablename;

// find an item that has `#text` property equal to `QaQcPoints`
var item = _.find(table, function(r) {
  return r['#text'] === 'QaQcPoints';
});

// extract codes from the found item's record property
var code = extract(item.record, 'Code');
// output ["tp", "tb", "to", "bl", "bf"]

运行样本:

var JSONData = {
  "surveyGDB": {
    "filename": "..\Topo\SurveyGeoDatabase.gdb",
    "table": {
      "tablename": [{
        "#text": "SurveyInfo",
        "record": {
          "OBJECTID": "1",
          "SiteID": "CBW05583-345970",
          "Watershed": "John Day",
          "VisitType": "Initial visit",
          "SurveyInstrument": "Total Station",
          "ImportDate": "2015-07-22T09:08:42",
          "StreamName": "Duncan Creek",
          "InstrumentModel": "TopCon Magnet v2.5.1",
          "FieldSeason": "2015"
        }
      }, {
        "#text": "QaQcPoints",
        "record": [{
          "OBJECTID": "1",
          "TIMESTAMP": "2015-07-22T09:18:43",
          "Code": "tp",
          "Count": "357"
        }, {
          "OBJECTID": "2",
          "TIMESTAMP": "2015-07-22T09:18:43",
          "Code": "tb",
          "Count": "92"
        }, {
          "OBJECTID": "3",
          "TIMESTAMP": "2015-07-22T09:18:43",
          "Code": "to",
          "Count": "8"
        }, {
          "OBJECTID": "4",
          "TIMESTAMP": "2015-07-22T09:18:43",
          "Code": "bl",
          "Count": "279"
        }, {
          "OBJECTID": "5",
          "TIMESTAMP": "2015-07-22T09:18:43",
          "Code": "bf",
          "Count": "18"
        }]
      }, {
        "#text": "QaQcPolygons",
        "record": [{
          "OBJECTID": "1",
          "TIMESTAMP": "2015-07-22T09:43:08",
          "SurveyExtentCount": "",
          "WaterExtentCount": "",
          "ChannelUnitsCount": "",
          "ChannelUnitsUnique": ""
        }, {
          "OBJECTID": "2",
          "TIMESTAMP": "2015-07-22T13:35:15",
          "SurveyExtentCount": "1",
          "WaterExtentCount": "1",
          "ChannelUnitsCount": "21",
          "ChannelUnitsUnique": "21"
        }]
      }]
    }
  }
}

function extract(record, prop) {
  if (Array.isArray(record)) {
   return _.pluck(record, prop);
  } else {
    return record[prop];
  }
}

var table = JSONData.surveyGDB.table.tablename;

var item = _.find(table, function(r) {
  return r['#text'] === 'QaQcPoints';
});

console.dir(item);

var code = extract(item.record, 'Code');

console.log(code);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>

你有一个两阶段的问题。第一阶段是找出哪个 table 是 QaQcPoints。如果那总是 JSONData.surveyGDB.table.tablename[1],那你很好。

下一阶段是获取数据。大多数时候您可以使用本机数组操作(除非您使用的是非常旧的浏览器)。所以:

var table = JSONData.surveyGDB.table.tablename[1].record;
var codeArray = table.map(function(val) { return val.Code; });

会成功的。