读取 json 文件中的嵌套值 - 使用 JS

Reading nested values within json file - with JS

我正在尝试从 JSON 文件中读取值。 到目前为止,我可以读到 stopTime 但我不知道如何读取之后的嵌套值。

我的 JSON 文件

 "description": [
    {
    "id": " an id number",
    "something 1": "xxxx",
    "something 2": "yyyy",
    "startTime": "2017-12-27T18:47:15.000+0000",
    "stopTime": "2017-12-27T18:47:15.000+0000",
    "mediaFiles": [
        {
        "mediaUri": " some url value",
        "mediaPath": "some path value",
        "startTime": " a time",

我的 JS 代码有效。

var J = [];
$.getJSON( "calls/jsonfile.json", function( data){
  J = data;
  var x = 48;
  for(x=0;x<48;++x) {
     var id = J.description[x].id;
     ...
  }
}

这很好用,我得到了我正在寻找的值。

非常感谢任何帮助...我对这些东西很陌生。

for(x=0;x<48;++x) {
    var id = J.description[x].id;
    // You can loop over the mediaFiles like this:
    for( num in J.description[x].mediaFiles ) {
        var theURI  = J.description[x].mediaFiles[num].mediaUri
        var thePath = J.description[x].mediaFiles[num].mediaPath
        ...
    }
    ...
}

首先,不要硬编码 x < 48。使用 J.description.length,这样无论数组的实际长度如何,您的代码都将始终正确执行。

你想要这样的东西:

for (var x = 0; x < J.description.length; x++) {
    var descEntry = J.description[x];
    var id = descEntry.id;
    // do stuff with the description entry
    ...

    for (var y = 0; y < descEntry.mediaFiles.length; y++) {
        var fileEntry = descEntry.mediaFiles[y];
        // do stuff with the file entry
        ...
    }
}

第一个 for 循环将在 J.description 的所有索引上迭代 x。我为当前条目添加了一个变量以简化操作。第二个 for 循环将在 descEntry.mediaFiles(又名 J.description[x].mediaFiles)的所有索引上迭代 y

同样的事情,使用 for-each 循环遍历数组键(索引):

for (var x in J.description) {
    var descEntry = J.description[x];
    var id = descEntry.id;
    // do stuff with the description entry
    ...

    for (var y in descEntry.mediaFiles) {
        var fileEntry = descEntry.mediaFiles[y];
        // do stuff with the file entry
        ...
    }
}

同样的事情,使用 new ES2015 features for-each 循环遍历数组值:

for (var descEntry of J.description) {
    var id = descEntry.id;
    // do stuff with the description entry
    ...

    for (var fileEntry of descEntry.mediaFiles) {
        // do stuff with the file entry
        ...
    }
}

您的 JavaScript 环境可能不支持 ECMAScript 2015 (ES6) 功能。 此外,如果您尝试遍历非标准数组(例如,添加了额外属性的数组)。

您可以使用一些基本函数 javascript 从 json 数组中获取值。只需使用几个函数,您就可以构建从数据集合中获取任何值的能力。

  • compose - 加入多个函数
  • flatMap - 展平一个 2 级数组,运行 每个值的函数
  • map - 对数组中的每个元素运行一个函数,返回一个具有新值的新数组
  • prop - 获取对象的 属性

使用函数式编程的好处是您可以通过组合可单独测试的函数来创建小型应用程序。您可以从 ramdajs.

这样的库中获取这些函数

const json = {
  "description": [
    {
      "id": 1,
      "mediaFiles": [
        { "mediaUri": "/images/1_1.png" },
        { "mediaUri": "/images/1_2.png" },
      ]
    },
    {
      "id": 2,
      "mediaFiles": [
        { "mediaUri": "/images/2_1.png" },
        { "mediaUri": "/images/2_2.png" },
      ]
    }
  ]
}

const prop = name => obj => obj[name]
const compose = (...fns) => x => fns.reduceRight((x, fn) => fn(x), x)
const map = fn => arr => arr.map(fn)
const flatMap = fn => arr => arr.reduce((acc, x) => acc.concat(fn(x)), [])

const getIds = compose(
  map(prop('id')),
  prop('description')
)

const getMediaUris = compose(
  flatMap(
    compose(
      map(prop('mediaUri')),
      prop('mediaFiles')
    )
  ),
  prop('description')
)

console.log(
  getIds(json)
)

console.log(
  getMediaUris(json)
)

expect('prop retrieves an object property', () => {
  assert(
    prop('one')({ one: 1 })
  ).equal(1)
})

expect('compose joins multiple functions', () => {
  assert(
    compose(
      z => z + 1,
      y => y + 1,
      x => x + 1
    )(0)
  ).equal(3)
})

expect('flatMap folds array', () => {
  assert(
    flatMap(x => x)([[1], [2]])
  ).deepEqual([1, 2])
})
<script src="https://codepen.io/synthet1c/pen/KyQQmL.js"></script>