如何在对象中分配对象并过滤通过和失败的值;
输入为:
[
{
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吗?以及我们为此使用了多少个循环? 我很想知道如何在该输出旁边的对象中添加另一个字符串, 谢谢
答案 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个属性的对象:分别为evening
和morning
其中是一个包含类的数组。
grpV
:用于按值分组的函数(在这种情况下为75
),该函数返回具有2个属性的对象:pass
和fail
每个都是包含类的数组。
最后,一旦有了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
值是否存在,并创建pass
和fail
键。然后针对.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));