user1752759
user1752759

Reputation: 643

Get nested object count of key value pair

I am creating a React app and have the following list:

const list = [
    {
        id: '1',
        group: 'sports 1',
        sports: [{
            'basketball': [
                {competed: true},
                {won: false}
            ],
            'soccer': [
                {competed: false},
                {won: false}
            ],
            'hockey': [
                {competed: false},
                {won: false}
            ]
        }],
        competedInAll: false
    },
    {
        id: '2',
        group: 'sports 2',
        sports: [{
            'tennis': [
                {competed: false},
                {won: false}
            ],
            'swimming': [
                {competed: false},
                {won: false}
            ],
            'baseball': [
                {competed: false},
                {won: false}
            ]
        }],
        competedInAll: false
    },
    {
        id: '3',
        group: 'sports 3',
        sports: [{
            'volleyball': [
                {competed: true},
                {won: false}
            ],
            'karate': [
                {competed: true},
                {won: false}
            ],
            'surfing': [
                {competed: true},
                {won: false}
            ]
        }],
        competedInAll: false
    }
];

I am iterating through the list like so:

<ul>
    {list.map(item => (
        <li key={item.id}>
           {item.group}
           <ul>
               {Object.keys(item.sports[0]).map((sport, i) => <li key={i}>{sport}</li>)}
           </ul>
        </li>
    ))}
</ul>

Which will produce the following output:

I am wanting to achieve:

  1. How can I get the total count of competed that equal false (grouped) in each of the sports?
  2. How can I set this count to 'competed in all sports' (grouped) when they are all set to true?

Upvotes: 1

Views: 430

Answers (2)

Abhishek-Saini
Abhishek-Saini

Reputation: 743

render(){
//here I put list in render but you can place in your code as you need
  const list = [
    {
      id: '1',
      group: 'sports 1',
      sports: [{
          'basketball': [
              {competed: true},
              {won: false}
          ],
          'soccer': [
              {competed: false},
              {won: false}
          ],
          'hockey': [
              {competed: false},
              {won: false}
          ]
      }],
      competedInAll: false
    },

    {
      id: '2',
      group: 'sports 2',
      sports: [{
          'tennis': [
              {competed: false},
              {won: false}
          ],
          'swimming': [
              {competed: false},
              {won: false}
          ],
          'baseball': [
              {competed: false},
              {won: false}
          ]
      }],
      competedInAll: false
    },

    {
      id: '3',
      group: 'sports 3',
      sports: [{
          'volleyball': [
              {competed: true},
              {won: false}
          ],
          'karate': [
              {competed: true},
              {won: false}
          ],
          'surfing': [
              {competed: true},
              {won: false}
          ]
      }],
      competedInAll: false
    }
  ];

  let remaining = [] // remaining variable is empty list we will push the number of remaining items which are false in the same sequence as our list item are. 

  //this loop is used to find out the number of completed = false and push in remaining list
  for(var i=0; i<list.length; i++){
    let count = 0;
    for (var key in list[i].sports[0]){
      if(!list[i].sports[0][key][0].competed){
        count = count + 1 
      }
    }
    remaining.push(count);
  }
  //loop end here

  return (
    <div>
      <ul>
        {list.map((item,index) => (
          <li key={item.id}>
            {item.group}(remaining: {remaining[index]})
            <ul>
              {Object.keys(item.sports[0]).map((sport, i) => <li key={i}>{sport}</li>)}
            </ul>
          </li>
        ))}
      </ul>
    </div>
  )
}

Things to note I have added index here list.map((item,index) =>{}) as a extra parameter to recieve in map() function and use this index in {item.group}(remaining: {remaining[index]})

Upvotes: 0

Dhananjai Pai
Dhananjai Pai

Reputation: 6015

const getStatus = (item) => {
  let length = Object.values(item.sports[0]).filter(x => !x[0].competed).length;
  /* 
  A more readable version below 
  let sports = item.sports[0];
  let sportDetails = Object.keys(sports);
  let notCompetedSports = sportDetails.filter(sport => sport[0].competed === false);
  let length = notCompletedSports.length'
  */
  return length === 0 ? 'competed in all sports' : length+" remaining"
}
<ul>
    {list.map(item => (
        <li key={item.id}>
           {item.group} ({getStatus(item)})
           <ul>
               {Object.keys(item.sports[0]).map((sport, i) => <li key={i}>{sport}</li>)}
           </ul>
        </li>
    ))}
</ul>

Upvotes: 1

Related Questions