Comment affecter l'objet dans objet et filtrer la valeur qui passe et échoue;

L'entrée est:

    [
      {
        name: 'John',
        score: 90,
        time: 'evening'
      },
      {
        name: 'Doni',
        score: 68,
        time: 'morning'
      },
      {
        name: 'Jiu',
        score: 50,
        time: 'evening'
      },
      {
        name: 'Shin',
        score: 92,
        time: 'morning'
      },
    ];

Et je veux la sortie comme ceci:

{
  "evening": {
    "pass": [
      {
        "name": "John",
        "score": 90
      }
    ],
    "fail": [
      {
        "name": "jiu",
        "score": 50
      }
    ]
  },
  "morning": {
    "pass": [
      {
        "name": "Shin",
        "score": 92
      }
    ],
    "fail": [
      {
        "name": "Doni",
        "score": 68
      }
    ]
  }
}

Avons-nous besoin d'utiliser Object.assign pour cela? et combien de boucles nous utilisons pour cela ?? j'aime savoir comment ajouter une autre chaîne dans l'objet à côté de cette sortie, merci

1
Zr Classic 20 nov. 2018 à 03:20

3 réponses

Meilleure réponse

Vous pouvez faire quelque chose comme ça:

const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];

const grp = (d, p) => d.reduce((r,c) => (r[c[p]] = [...r[c[p]] || [], c], r), {})
const grpV = (d, rng) => d.reduce((r,{name, score}) => {
  let key = score > rng ? 'pass' : 'fail'
  r[key] = [...r[key] || [], {name, score}]
  return r
}, {})

const r = Object.entries(grp(data, 'time')).map(([k,v]) => ({[k]: grpV(v, 75)}))

console.log(r)

L'idée est le groupe 2 fois un le time et 2e le score.

grp : fonction de regroupement par une propriété (dans ce cas 'time') qui renvoie un objet avec 2 propriétés: evening et morning chacune étant un tableau contenant les classes.

grpV : fonction de regroupement par valeur (dans ce cas 75) qui renvoie un objet avec 2 propriétés: pass et fail chacune est un tableau contenant les classes.

À la fin, une fois que nous avons ces tools, nous disons ... donnez-moi le entries de l'objet groupé par time et pour chacun des groupes ... groupez par score.

Voici à quoi pourrait ressembler quelque chose comme ça si nous utilisons lodash :

const data = [{ name: 'John', score: 90, time: 'evening' }, { name: 'Doni', score: 68, time: 'morning' }, { name: 'Jiu', score: 50, time: 'evening' }, { name: 'Shin', score: 92, time: 'morning' }, ];

const partition = (x, p) => _(x)
  .partition(y => y.score > p)
  .map((x,i) => ({ [i==0 ? 'pass': 'fail']: _.omit(x[0], 'time')}))
  .value()

const r = _(data)
  .groupBy('time')
  .mapValues(x => partition(x, 75))
  .value()

console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

L'ajouter en tant qu'exemple car cela aide à la lisibilité de ce que fait l'exemple ES6 dans une certaine mesure.

2
Akrion 20 nov. 2018 à 01:43

Il existe de nombreuses façons de procéder. Le plus simple est probablement de créer un objet de base qui représente vos résultats vides. Faites ensuite une boucle sur les élèves et remplissez les tableaux:

let students = [{name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];

// Empty case
let base =  {
        "evening": {"pass": [], "fail": []},
        "morning": {"pass": [], "fail": []}
}

const PASSING = 70

students.forEach(({name, score, time}) => {
    let key = score >= PASSING ? 'pass' : 'fail'
    base[time][key].push({name, score})
})
console.log(base)

Cela rend facile d'avoir des tableaux vides, ce qui est probablement ce que vous voulez s'il n'y a pas d'élèves dans une catégorie particulière.

EDIT basé sur le commentaire:

Pour prendre en charge les heures arbitraires, vous pouvez simplement créer les heures sur l'objet au fur et à mesure que vous les trouvez. reduce() est bon pour cela, mais vous pouvez également utiliser une boucle régulière. Par exemple, avec un afternoon temps ajouté:

let students = [{name: 'Mark',score: 95,time: 'afternoon'}, {name: 'John',score: 90,time: 'evening'},{name: 'Doni',score: 68,time: 'morning'},{name: 'Jiu',score: 50,time: 'evening'},{name: 'Shin',score: 92,time: 'morning'},];

const PASSING = 70

let result = students.reduce((obj, {name, score, time}) => {
    if (!obj[time]) obj[time] = {'pass': [], 'fail': [] }

    let key = score >= PASSING ? 'pass' : 'fail'
    obj[time][key].push({name, score})

    return obj
}, {})


console.log(result)
3
Mark Meyer 20 nov. 2018 à 01:35

Je suis sûr qu'il existe des façons plus élégantes de le faire. Mais celui-ci est probablement l'un des moyens les plus simples pour les débutants.

Je parcourt le tableau d'entrée, vérifie l'existence des valeurs .time en tant que clés sur l'objet output et crée les clés pass et fail. Évaluez ensuite le .score par rapport au passingScore et envoyez-y les données nécessaires.

Cela devrait être assez facile à comprendre une fois que vous voyez et essayez le code ci-dessous:

const data =   [
      {name: 'John',score: 90, time: 'evening'},
      {name: 'Doni',score: 68, time: 'morning'},
      {name: 'Jiu',score: 50, time: 'evening'},
      {name: 'Shin',score: 92, time: 'morning'},
      {name: 'Fubar',score: 75, time: 'noon'},
    ];
    
    
function formatData(data){
   const passingScore = 75;
   const output = {};

   data.forEach(function(item){
      if(!output[item.time]) output[item.time] = {pass: [], fail: []};

      const stud = { name: item.name, score: item.score };
        
      if(item.score >= passingScore) output[item.time]['pass'].push(stud)
      else output[item.time]['fail'].push(stud)  
   });

   return output;
}

console.log(formatData(data));
1
Abana Clara 20 nov. 2018 à 04:53