J'ai cette liste ci-dessous, obtenant des données de l'api:
[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"}]
et je rend ces données comme ceci:
Object.values(Studentdata).sort((a, b) => b.active - a.active)
Donc, Ici, je veux filtrer les données des élèves en fonction de leur activité, les vrais éléments actifs doivent passer en premier. L'op attendue est:
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" } }
Je l'utilise dans React js, donc j'ai besoin d'un format exact pour rendre / re-rendre le DOM. Parce que j'ai besoin de ce "StudentName1" pour afficher le nom de l'élève sous celui-ci, je vais montrer ses détails. Je peux obtenir ce qui suit:
Object.keys(Studentdata).map(item => { return ( <> <span>{item}</span> // will use {Studentdata[item]} list to render ul,li ) })
mais cela me donne:
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" } }
Mais si je rend ceci, je besoin de changer la méthode de rendu, donc besoin du format que j'ai mentionné ci-dessus.Merci
3 Réponses :
Le problème est que vous n'utilisez que les values ()
pour effectuer le tri, alors que vous devriez également trier les objets avec les clés. L'autre problème que vous rencontrez est que ce n'est généralement pas une bonne pratique de désirer que vos clés d'objet soient dans un ordre particulier. Il est beaucoup plus logique de changer votre fonction de rendu en results.map
au lieu de Object.keys (results) .map
. Voici la sortie souhaitée:
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)
Si vous supprimez le reduction ()
, vous obtiendrez les résultats souhaités, mais simplement dans un tableau. Ceci est préférable, car la réduction est redondante, car vous le retournez de toute façon en tableau avec Object.keys ()
. De plus, si l’ordre des clés doit être maintenu de nos jours, il n’est toujours pas intuitif de s’y fier.
Si je supprime réduire (), je n'obtiens pas le résultat souhaité.
J'ai dit, «mais simplement dans un tableau» si vous supprimez réduire (les données sont toujours les mêmes). Vous devez améliorer votre fonction de rendu pour travailler avec des tableaux plutôt qu'avec des objets.
Triez les entrées de l'objet (pas seulement les clés) lors de la préparation du rendu, afin d'avoir un tableau trié contenant les clés et les valeurs associées à la fois:
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 ))
Puis-je savoir quel est le terme pour l'appel entre crochets dans [name, {active, gender}]
?
C'est de la déstructuration. Au lieu de item
, vous pouvez utiliser [val0, val1]
pour extraire le 0ème et le 1er index du tableau, si item
est un tableau. De même, vous pouvez utiliser {active, gender}
pour extraire la propriété active
et gender
de val1
, si < code> val1 est un objet.
Triez sur Object.entries
, puis reconstruisez l'objet dans votre instruction map (en utilisant malheureusement eval
pour conserver le nom de la variable):
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> ) ));