2

I have this below list, getting data from api :

 const Studentdata = {
   "StudentName1": {
        "active": true,
        "gender": "male" 
    },
    "StudentName2": {
        "active": false,
        "gender": "male" 
    },
    "StudentName3": {
        "active": false,
        "gender": "female" 
    },
   "StudentName4": {
        "active": true,
        "gender": "female" 
    },
   "StudentName5": {
        "active": true,
        "gender": "female" 
    },
    "StudentName6": {
        "active": false,
        "gender": "female" 
    }
}

and I render this data like this:

Object.keys(Studentdata).map(item => {
    return (
         <>
             <span>{item}</span>
             // will use {Studentdata[item]} list to render ul,li
    )

 })

So, here I Want to filter student data based on is she/he is active, active true items should come first. Expected op is:

const Studentdata = {
   "StudentName1": {
        "active": true,
        "gender": "male" 
    },
    "StudentName4": {
        "active": true,
        "gender": "male" 
    },
    "StudentName5": {
        "active": true,
        "gender": "female" 
    },
   "StudentName2": {
        "active": false,
        "gender": "female" 
    },
   "StudentName3": {
        "active": false,
        "gender": "female" 
    },
    "StudentName6": {
        "active": false,
        "gender": "female" 
    }
}

I am using it in React js, So I need to exact format to render / re-render the DOM. Because, I need this "StudentName1" to displan student name under this I Will show his details. I'm able to get the below:

Object.values(Studentdata).sort((a, b) => b.active - a.active)

but this gives me:

[0: {active: true, gender: "male"},
1: {active: true, gender: "female"},
2: {active: true, gender: "female"},
3: {active: false, gender: "male"},
4: {active: false, gender: "female"}]

But if I render this I need to change the render method, So need the format I mentioned above.Thanks

3 Answers 3

2

Sort the object's entries (not just the keys) when preparing to render, so that you have a sorted array containing the keys and the associated values at once:

Object.entries(Studentdata)
  .sort((a, b) => b[1].active - a[1].active)
  .map(([name, { active, gender }]) => (
    // render ul, li with variables name, active, and gender
  ))
Sign up to request clarification or add additional context in comments.

2 Comments

May I know what is the term for the square bracket call in [name, { active, gender }]?
That's destructuring. Instead of item, you can use [val0, val1] to extract the 0th and 1st index of the array, if item is an array. Similarly, you can use { active, gender } to extract the active and gender property of val1, if val1 is an object.
1

The problem is that you are only using the values() to perform the sort, when you should be sorting the objects with the keys as well. The other problem you have, is that it is not generally good practice to desire your object keys to be in a particular order. It makes much more sense to change your render function to results.map instead of Object.keys(results).map. Here is your desired output though:

const Studentdata = {
 "StudentName1": {
      "active": true,
      "gender": "male" 
  },
  "StudentName2": {
      "active": false,
      "gender": "male" 
  },
  "StudentName3": {
      "active": false,
      "gender": "female" 
  },
 "StudentName4": {
      "active": true,
      "gender": "female" 
  },
 "StudentName5": {
      "active": true,
      "gender": "female" 
  },
  "StudentName6": {
      "active": false,
      "gender": "female" 
  }
}

const sorted = Object.entries(Studentdata)
  .sort((a, b) => b[1].active - a[1].active)
  .reduce((r, [key, value]) => {
    r[key] = value
    return r
  }, {})
  
console.log(sorted)

If you remove the reduce(), you will get your desired results, but simply in an array. This is preferable, because the reduce is redundant, as you are turning it back to an array anyway with Object.keys(). Also while key order should be maintained these days, it still feels unintuitive to rely on it.

2 Comments

If I remove reduce() I am not getting the desired output.
I said, 'but simply in an array' if you remove reduce (the data is still the same). You need to improve your render function to work with arrays instead of objects.
1

Sort on Object.entries, then reconstruct the object in your map statement (using eval unfortunately to preserve the variable name):

const Studentdata = {
   "StudentName1": {
        "active": true,
        "gender": "male" 
    },
    "StudentName2": {
        "active": false,
        "gender": "male" 
    },
    "StudentName3": {
        "active": false,
        "gender": "female" 
    },
   "StudentName4": {
        "active": true,
        "gender": "female" 
    },
   "StudentName5": {
        "active": true,
        "gender": "female" 
    },
    "StudentName6": {
        "active": false,
        "gender": "female" 
    }
};

Object.entries(Studentdata).sort((a, b) => b[1].active - a[1].active).map(([ name: objName, { active, gender } ]) => (
    eval(`let ${objName} = { active: ${active}, gender: ${gender} }`);
    return (
        <>
            <span>{name}</span>
    )
));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.