Home > OS >  JSON - return number of items within a list that have a specific key value
JSON - return number of items within a list that have a specific key value

Time:11-12

Having a bit of a nightmare trying to solve this JSON problem. I need to store the number of offers as a tally, but it needs to only be a number whereby the offers have an activated status. In the example below (simplified for illustration) the result should be 2 (as only only of them is false for the 'activated' key). I've tried to target it with this:

var count = Object.keys(object.allOffers[0].offers[0].activated.hasOwnProperty('true')).length;

^^^ but it returns 0. Furthermore it only selects the first offer and I need a method that will target all of the offers that sit inside allOffers. Any ideas? Sample code below.

object {
  "allOffers": [
    {
      "offers": [
        {
          "offerId": 15661,
          "activated": true,
          "viewed": false
        },
        {
          "offerId": 15641,
          "activated": false,
          "viewed": false
        },
        {
          "offerId": 16461,
          "activated": true,
          "viewed": true
        }
      ]
    }
  ]
}

CodePudding user response:

Your .offers[0] only targets the first element in the array, and checking whether the .activated string has an own property of 'true' doesn't make any sense.

Best method would be to use .reduce instead - iterate over the array, and add one to the accumulator for each object for which obj.activated is true.

const input = {
  "allOffers": [
    {
      "offers": [
        {
          "offerId": 15661,
          "activated": true,
          "viewed": false
        },
        {
          "offerId": 15641,
          "activated": false,
          "viewed": false
        },
        {
          "offerId": 16461,
          "activated": true,
          "viewed": true
        }
      ]
    }
  ]
};

const totalActivated = input.allOffers[0].offers
  .reduce((a, obj) => a   obj.activated, 0);
console.log(totalActivated);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

Filtering by those that are activated and then checking the length of the resulting array works too.

const input = {
  "allOffers": [
    {
      "offers": [
        {
          "offerId": 15661,
          "activated": true,
          "viewed": false
        },
        {
          "offerId": 15641,
          "activated": false,
          "viewed": false
        },
        {
          "offerId": 16461,
          "activated": true,
          "viewed": true
        }
      ]
    }
  ]
};

const totalActivated = input.allOffers[0].offers
  .filter(obj => obj.activated)
  .length;
console.log(totalActivated);
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related