简体   繁体   中英

how to assign object in object

how to assign the object in object and filter the value which pass and fail;

the input is:

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

and i want the output like this :

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

do we need to use Object.assign for this ? and how many loop we use for this ?? i do love to know how to add another string in the object beside that ouput, thanks

There's a lot of ways to do this. The simplest is probably to make a base object that represent your empty results. Then loop over the students and fill the arrays:

 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) 

This makes is easy to have empty arrays, which is probably what you want if there are no students in a particular category.

EDIT based on comment:

To support arbitrary times, you can just create the times on the object as you find them. reduce() is good for this, but you could also use a regular loop. For example with an added afternoon time:

 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) 

You can do something like this:

 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) 

The idea is the group 2 times one on the time and 2nd on the score .

grp : function to group by a property (in this case 'time') which returns an object with 2 properties: evening and morning each of which is an array containing the classes.

grpV : function to group by value (in this case 75 ) which returns an object with 2 properties: pass and fail each of which is an array containing the classes.

On the end once we have those tools we are saying ... give me the entries of the grouped by time object and for each of the groups ... group by score.

Here how something like this could look like if we ware using 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> 

Adding it as an example since it does help with readability of what the ES6 example is doing to some extend.

I'm sure there are more elegant ways to do this. But this one is probably one of the simplest beginner-friendly ways you can go about this.

I loop through the input array, check the existence of the .time values as keys on the output object and create the pass and fail keys. Then evaluate the .score against the passingScore and push the necessary data to it.

Should be pretty easy to understand once you see and try the code below:

 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)); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM