KateJean
KateJean

Reputation: 428

Analyzing Data from JSON in JavaScript

I'm not saying this is a completely smart idea (ideally calculations for large amounts of data should be done in the back end, I think) but humor me.

I am attempting to pull a view pieces of data from a JSON source and do a small bit of analysis. Given the following data source:

[
    {
        "group": "satellite-1",
        "data": [
            {
                "label": "feed-1a",
                "data": [
                    {"timeRange": [800, 820], "val": "TargetC"},
                    {"timeRange": [800, 820], "val": "TargetD"},
                    {"timeRange": [820, 840], "val": "TargetA"},
                    {"timeRange": [820, 840], "val": "TargetC"},
                    {"timeRange": [820, 840], "val": "TargetD"},
                    {"timeRange": [820, 840], "val": "TargetB"}
                ]
            },
            {
                "label": "feed-2a",
                "data": [
                    {"timeRange": [780, 800], "val": "TargetB"}
                ]
            }

        ]
    },
    {
        "group": "satellite-4",
        "data": [
            {
                "label": "feed-1b",
                "data": [
                    {"timeRange": [780, 800], "val": "TargetA"},
                    {"timeRange": [800, 820], "val": "TargetB"},
                    {"timeRange": [800, 820], "val": "TargetC"}
                ]
            },
            {
                "label": "feed-2b",
                "data": [
                    {"timeRange": [780, 800], "val": "TargetB"}
                ]
            }

        ]
    }
]

I want to determine:

  1. number of satellites
  2. number of satellite feeds
  3. most observant feed (i.e. which feed had the most targets)

However, I'm not getting the result I want. I think my loops are not working as expected (see comments):

var dataSet_initial = [
{
    "group": "satellite-1",
    "data": [
        {
            "label": "feed-1a",
            "data": [
                {"timeRange": [800, 820], "val": "TargetC"},
                {"timeRange": [800, 820], "val": "TargetD"},
                {"timeRange": [820, 840], "val": "TargetA"},
                {"timeRange": [820, 840], "val": "TargetC"},
                {"timeRange": [820, 840], "val": "TargetD"},
                {"timeRange": [820, 840], "val": "TargetB"}
            ]
        },
        {
            "label": "feed-2a",
            "data": [
                {"timeRange": [780, 800], "val": "TargetB"}
            ]
        }

    ]
},
{
    "group": "satellite-4",
    "data": [
        {
            "label": "feed-1b",
            "data": [
                {"timeRange": [780, 800], "val": "TargetA"},
                {"timeRange": [800, 820], "val": "TargetB"},
                {"timeRange": [800, 820], "val": "TargetC"}
            ]
        },
        {
            "label": "feed-2b",
            "data": [
                {"timeRange": [780, 800], "val": "TargetB"}
            ]
        }

    ]
}
];

/*
 * Prep Data
 */
var dataSet_stringify = JSON.stringify(dataSet_initial); // strigify JSON to parse it
var dataSet_parsed = JSON.parse(dataSet_stringify); // parse JSON

/*
 * # Satellites
 */
var getNumberofSatellites = dataSet_parsed.length; //2
console.log("Number of Satellites: " + getNumberofSatellites);

/*
 * # Feeds
 */
var getGroupList = function(){
    var i, j;

    for (i = 0; i < dataSet_parsed.length; i++) {
        for (j = 0; i < dataSet_parsed[i].data.length; j++){
            return dataSet_parsed[i].data[j].label;
        }
    }
}; //returns only the first feed, not looping through
console.log("Feeds: " + getGroupList());

/*
 * # of Feed Data Feeds
 */
var getMostObservantFeed = function(){
    var i, j;

    for (i = 0; i < dataSet_parsed.length; i++) {
        for (j = 0; i < dataSet_parsed[i].data[j].data.length; j++){
            return dataSet_parsed[i].data[j].data.length;
        }
    }
}; //again not looping through

console.log("Individual Feed Data Feeds: " + getMostObservantFeed());

Upvotes: 2

Views: 881

Answers (3)

Alcides Queiroz
Alcides Queiroz

Reputation: 9576

Well, did my own version for this, by using some Array magic:

  const satellitesData = getSatellitesData();
  const feeds = [].concat.apply([], satellitesData.map(s => s.data));

  // Extracting what you want...
  const satellitesCount = satellitesData.length;
  const feedsCount = feeds.length;
  const mostObservantFeed = feeds.reduce((a, b) => (a.data.length > b.data.length) ? a : b);

  console.table([{ 
    'Satellites count': satellitesCount, 
    'Feeds count': feedsCount,
    'Most observant feed': mostObservantFeed.label
  }]);


  // Your data, which will be retrieved from somewhere...
  function getSatellitesData() {
    return [
      {
        group: 'satellite-1',
        data: [
          {
            label: 'feed-1a',
            data: [
              {
                timeRange: [800, 820],
                val: 'TargetC'
              },
              {
                timeRange: [800, 820],
                val: 'TargetD'
              },
              {
                timeRange: [820, 840],
                val: 'TargetA'
              },
              {
                timeRange: [820, 840],
                val: 'TargetC'
              },
              {
                timeRange: [820, 840],
                val: 'TargetD'
              },
              {
                timeRange: [820, 840],
                val: 'TargetB'
              }
            ]
          },
          {
            label: 'feed-2a',
            data: [
              {
              timeRange: [780, 800],
              val: 'TargetB'
            }]
          }

        ]
      },
      {
        group: 'satellite-4',
        data: [
          {
            label: 'feed-1b',
            data: [
              {
                timeRange: [780, 800],
                val: 'TargetA'
              },
              {
                timeRange: [800, 820],
                val: 'TargetB'
              },
              {
                timeRange: [800, 820],
                val: 'TargetC'
              }
            ]
          },
          {
            label: 'feed-2b',
            data: [
              {
              timeRange: [780, 800],
              val: 'TargetB'
            }]
          }

        ]
      }
    ];
  }

Commented version

// For the sake of clarity, I just extracted the example data to 
// a separate function...
const satellitesData = getSatellitesData();

/*
As the items of the original satellitesData array were objects, I needed to 
simplify them, by making a `map` first. So, instead of an array of objects 
whose items had an array property each one ("data"), after doing the map, 
I'll have simply an array of arrays.
To make it even simpler, I use `[].concat.apply([], someArrayHere)` 
to flatten our bidimensional array. 
In the end, by using this trick, I create a flat array of feeds.
*/
const feeds = [].concat.apply([], satellitesData.map(s => s.data));


const satellitesCount = satellitesData.length;

// As I have an array of feeds above, it's just a question of getting 
// the array length in order to find the feeds count
const feedsCount = feeds.length;

// Now I'm using reduce to iterate over the feeds. In each iteration, 
// I'm comparing the targets count, to find the feed with more targets. 
// At the end, the reduce will return the most observant feed.
const mostObservantFeed = feeds.reduce((a, b) => (a.data.length > b.data.length) ? a : b);

// To finish, console.table is just a fancy way of showing the data in the console. =)
console.table([{ 
  'Satellites count': satellitesCount, 
  'Feeds count': feedsCount,
  'Most observant feed': mostObservantFeed.label
}]);

Upvotes: 2

Ben Che
Ben Che

Reputation: 79

number of satellites

your JSON object is an array/collection of satellite objects, so the length attribute is a good way to do it. Assuming JSON is the variable loaded with the JSON data you have, then JSON.length would be fine (I wouldn't use JSON as a variable name just because it conflicts with Javascript's built-in JSON object.

number of satellite feeds

iterate through individual JSON.data.length values for each satellite

most observant feed

see JSFiddle here -> https://jsfiddle.net/pLgnv9pL/

Upvotes: 1

Stacey Reiman
Stacey Reiman

Reputation: 695

Here is a way you could get these values - I would not use 'JSON' for the name of your data, as you can't use JSON.stringify if you use that as your data var name.

var data = [
{
    "group": "satellite-1",
    "data": [
        {
            "label": "feed-1a",
            "data": [
                {"timeRange": [800, 820], "val": "TargetC"},
                {"timeRange": [800, 820], "val": "TargetD"},
                {"timeRange": [820, 840], "val": "TargetA"},
                {"timeRange": [820, 840], "val": "TargetC"},
                {"timeRange": [820, 840], "val": "TargetD"},
                {"timeRange": [820, 840], "val": "TargetB"}
            ]
        },
        {
            "label": "feed-2a",
            "data": [
                {"timeRange": [780, 800], "val": "TargetB"}
            ]
        }

    ]
},
{
    "group": "satellite-4",
    "data": [
        {
            "label": "feed-1b",
            "data": [
                {"timeRange": [780, 800], "val": "TargetA"},
                {"timeRange": [800, 820], "val": "TargetB"},
                {"timeRange": [800, 820], "val": "TargetC"}
            ]
        },
        {
            "label": "feed-2b",
            "data": [
                {"timeRange": [780, 800], "val": "TargetB"}
            ]
        }

    ]
}
]

var getNumberofSatellites = data.length; //2

console.log('num sats: '+getNumberofSatellites)
console.log('group list: '+getGroupList())
console.log('most observant feed: '+getMostObservantFeed())

function getGroupList(){
  var groupNamesArray = [];
  for (i = 0; i < data.length; i++) {
     var name = data[i].group;
     groupNamesArray.push(name)
  }
  return groupNamesArray
}; 

function getMostObservantFeed(){
  var topFeed = '';
  var feedQuantity = 0;
  
  for (var i = 0; i < data.length; i++) {
    var sat = data[i].data;
    for (var j = 0; j < sat.length; j++) {
       var len = sat[j].data.length;

       if (len > feedQuantity) {
         feedQuantity = len
         topFeed = sat[j].label;
       }
     }
  }
  return topFeed
 };

Upvotes: 0

Related Questions