如何在对象中分配对象

时间:2018-11-20 00:20:53

标签: javascript arrays object iterator

如何在对象中分配对象并过滤通过和失败的值;

输入为:

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

我想要这样的输出:

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

我们需要为此使用Object.assign吗?以及我们为此使用了多少个循环? 我很想知道如何在该输出旁边的对象中添加另一个字符串, 谢谢

3 个答案:

答案 0 :(得分:3)

有很多方法可以做到这一点。最简单的方法可能是制作一个代表空结果的基础对象。然后遍历学生并填充数组:

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)

这使得空数组很容易,如果没有特定类别的学生,这可能就是您想要的。

根据评论进行编辑:

要支持任意时间,您可以在找到对象时在对象上创建时间。 reduce()对此很有用,但是您也可以使用常规循环。例如,增加了afternoon时间:

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)

答案 1 :(得分:2)

您可以执行以下操作:

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)

这个想法是该小组在time上两次乘以score上的第二乘。

grp :用于按属性(在本例中为“时间”)分组的函数,该属性返回具有2个属性的对象:分别为eveningmorning其中是一个包含类的数组。

grpV :用于按值分组的函数(在这种情况下为75),该函数返回具有2个属性的对象:passfail每个都是包含类的数组。

最后,一旦有了tools,我们就是说...给我entries对象分组的time,对于每个组... group by得分。

如果我们使用 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>

将其添加为示例,因为它确实有助于提高ES6示例所做的扩展的可读性。

答案 2 :(得分:1)

我敢肯定有更优雅的方法可以做到这一点。但这可能是您可以做到的最简单的初学者友好方式之一。

我循环遍历输入数组,检查.time对象中作为键的output值是否存在,并创建passfail键。然后针对.score评估passingScore并将必要的数据推送到其中。

一旦您看到并尝试以下代码,应该会很容易理解

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