简体   繁体   中英

How to access a specific element in nested array in JSON data using JavaScript?

I have JSON data which is structured as below. Intension is to look up a specific datapoint, eg annual profit, which is 5000.

I want to do this by finding the column by name, eg "profit", identify the column index (3 in the example), and then use the column index to select the nth (3rd) element in the second node ("annual") of the "data" array.

How can I do this using the findIndex() function in Javascript (see the key part of my code below)?

JSON data:

 { "datatable": { "data": [ [ "AAPL", "quarterly", 1000, 2000 ], [ "AAPL", "annual", 5000, 10000 ] ], "columns": [{ "name": "ticker" "type": "String" }, { "name": "timedim" "type": "String" }, { "name": "profit", "type": "Integer" }, { "name": "revenue", "type": "Integer" } ] } } 

JavaScript code:

  // daten contains the "data" array of the JSON dataset // spalten contains the "columns" array of the JSON dataset var i = spalten.findIndex(obj => obj.name == "profit"); output += '<p>Annual profit AAPL: ' + daten[i] + '</p>'; elroot.innerHTML += output; 

Based on the JSON structure you've given, the following will work. Writing a function would be good if you want to get specific profit based on parameters.

  var output = ""
  function getProfit(type="annual", column=2) {
    var arrForType = yourData.datatable.data.find(arr => arr.indexOf(type) !== -1);
    return arrForType[column];
  }

  var i = yourData.datatable.columns.findIndex(obj => obj.name == "profit");
  output += '<p>Annual profit AAPL: ' + getProfit("annual", i) + '</p>';
  document.body.innerHTML += output;

You have 2-dimensional array, so, you need two indexes:

const json = {
  "datatable": {
    "data": [
      [
        "AAPL",
        "quarterly",
        1000,
        2000
      ],
      [
        "AAPL",
        "annual",
        5000,
        10000
      ]
    ],
    "columns": [{
        "name": "ticker",
        "type": "String"
      },
      {
        "name": "timedim",
        "type": "String"
      },
      {
        "name": "profit",
        "type": "Integer"
      },
      {
        "name": "revenue",
        "type": "Integer"
      }
    ]
  }
}
var profitIndex = json.datatable.columns.findIndex(item => item.name == 'profit');
var annualIndex = json.datatable.data.findIndex(array => array.indexOf('annual') > -1);
var annualProfit = json.datatable.data[annualIndex][profitIndex];

If you need a function, it could look like below:

var getValueFromJson = function (json, columnName, dataMarker) {
    var columnIndex = json.datatable.columns.findIndex(item => item.name == columnName);
    var dataMarkerIndex = json.datatable.data.findIndex(array => array.indexOf(dataMarker) > -1);
    if (columnIndex < 0 || dataMarkerIndex < 0) {
        return null;
    }
    return json.datatable.data[dataMarkerIndex][columnIndex];
}

console.log(getValueFromJson(json, 'profit', 'quarterly'));
console.log(getValueFromJson(json, 'profit', 'annual'));
console.log(getValueFromJson(json, 'revenue', 'quarterly'));
console.log(getValueFromJson(json, 'revenue', 'annual'));

Above code prints:

> 1000
> 5000
> 2000
> 10000

This is the basic idea, then if you need to scale obviously you'll need to do this in a nicer way.

let output = '';

// Searches the desired index (refactor as needed)
const index = spalten.findIndex(obj => obj.name == "profit")

// Extract all the profits (if you dont need all just select the desired one)
daten.map(item => output += `<p>${item[1]} profit ${item[0]}: ${item[index]}</p>`)

You don't need findIndex - just use find and includes like so:

 const data = { "datatable": { "data": [ [ "AAPL", "quarterly", 1000, 2000 ], [ "AAPL", "annual", 5000, 10000 ] ], "columns": [{ "name": "ticker", "type": "String" }, { "name": "timedim", "type": "String" }, { "name": "profit", "type": "Integer" }, { "name": "revenue", "type": "Integer" } ] } }; function findValue(type) { return data.datatable.data.find(e => e.includes(type))[2]; } console.log(findValue("annual")); console.log(findValue("quarterly")); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM