Javascript 我想根据我的结果定制对象数组

Javascript 我想根据我的结果定制对象数组,javascript,node.js,arrays,Javascript,Node.js,Arrays,基本上我知道数组,它是原型方法, 我尝试使用new Set()、map和filter来获得结果。 但不知何故,我坚持在某个点,以获得预期的结果 下面是有关问题的详细信息以及我希望得到的结果 结果我得到了 让arr=[ { 日期:“2021-05-01”, 状态:“不完整”, }, { 日期:“2021-05-07”, 状态:“不完整”, }, { 日期:“2021-05-31”, 状态:“完成”, }, { 日期:“2021-05-31”, 状态:“不完整”, }, ]; 我想像下面这样转换这

基本上我知道数组,它是原型方法, 我尝试使用new Set()、map和filter来获得结果。 但不知何故,我坚持在某个点,以获得预期的结果

下面是有关问题的详细信息以及我希望得到的结果

结果我得到了
让arr=[
{
日期:“2021-05-01”,
状态:“不完整”,
},
{
日期:“2021-05-07”,
状态:“不完整”,
},
{
日期:“2021-05-31”,
状态:“完成”,
},
{
日期:“2021-05-31”,
状态:“不完整”,
},
];
我想像下面这样转换这个结果, 注:以日期为准

finalResult=[
{
日期:“2021-05-01”,
未完成:1,
完成日期:0,
总数:1,
},
{
日期:“2021-05-07”,
未完成:1,
完成日期:0,
总数:1,
},
{
日期:“2021-05-31”,
未完成:1,
完成日期:1,
总数:2,
},
];

感谢您的贡献

您可以通过组合使用
Set
map
功能来实现这一点。首先,您必须从数组中提取唯一的日期。我们可以使用
map
过滤掉日期,然后使用
Set
只保留唯一值。从这里了解有关集合的更多信息:

现在,我们在
日期
数组中有了唯一的三个日期,我们可以轻松地迭代每一个日期,并在下一个日期计算
完成
未完成
任务

const final = dates.map(date => {
    const incomplete = arr.filter(a => a.Date == date && a.Status == "incomplete").length
    const complete = arr.filter(a => a.Date == date && a.Status == "Complete").length

    return {
        Date: date,
        Incompleted: incomplete,
        Completed: complete,
        total: complete + incomplete
    }
})
最后:-
让arr=[
{
日期:“2021-05-01”,
状态:“不完整”,
},
{
日期:“2021-05-07”,
状态:“不完整”,
},
{
日期:“2021-05-31”,
状态:“完成”,
},
{
日期:“2021-05-31”,
状态:“不完整”,
},
];
const dates=[…新集合(arr.map(a=>a.Date))]
const final=dates.map(日期=>{
const complete=arr.filter(a=>a.Date==Date&&a.Status==“complete”).length
const complete=arr.filter(a=>a.Date==Date&&a.Status==“complete”).length
返回{
日期:日期:,
不完整的:不完整的,
完成:完成,
总计:完整+不完整
}
})

console.log(final)
您可以使用array
reduce
功能解决您的问题。它只遍历数组一次。我们创建一个以日期为键的新对象。如果对象中还不存在日期,则会为其创建一个新的空条目。然后,它将现有条目与当前元素合并

最后,我们需要使用
Object.values
再次将其转换为数组

const uniqueDates=arr.reduce((acc,cur)=>{
const existing=acc[cur.date]??createEmpty(cur);
返回{…acc,[当前日期]:合并(现有,当前)}
}, {})
const finalResult=对象值(唯一日期);
函数createEmpty({date}){
返回{日期,未完成:0,已完成:0,总计:0}
}
函数合并(现有,{status}){
返回{
……现有,
未完成:现有。未完成+状态==='未完成',
已完成:现有。已完成+状态===“已完成”,
总计:现有。总计+1
}
}

您可以对任何数量的
状态进行动态设置

  • 创建一个
    集合
    状态
    以获取所有唯一状态
  • 创建一个局部对象,所有状态都作为键,0作为其值。有很多方法可以创建它。我正在使用
    Object.fromEntries
    。它将如下所示:
    {“Complete”:0,“Complete”:0}
  • 在数组中循环。使用
    对象,每个
    日期
    作为键,输出中需要的对象作为其值
const arr=[{Date:“2021-05-01”,Status:“uncomplete”,},{Date:“2021-05-07”,Status:“uncomplete”,},{Date:“2021-05-31”,Status:“uncomplete”,},{Date:“2021-05-31”,Status:“uncompleted”,
唯一=新集合(arr.map(a=>a.Status)),
initial=Object.fromEntries(Array.from(unique,s=>[s,0]),
组={}
用于(arr的常数{日期,状态}){
组[日期]| |={日期,…首字母,总计:0};
组[日期][状态]++;
组[日期]。总计++
}
常量输出=对象值(组)

log(输出)
只需使用forEach循环即可

让arr=[
{
日期:“2021-05-01”,
状态:“不完整”,
},
{
日期:“2021-05-07”,
状态:“不完整”,
},
{
日期:“2021-05-31”,
状态:“完成”,
},
{
日期:“2021-05-31”,
状态:“未完成”,
},
]
让finalResult=[]
常量getDateEntryIndex=(日期)=>{
让索引=未定义
finalResult.forEach((元素,i)=>{
如果(element.Date==日期){
指数=i
}
})
回报指数
}
arr.forEach(元素=>{
让index=getDateEntryIndex(element.Date)
如果(索引){
如果(element.Status==“完成”){
最终结果[索引]。已完成++
}否则{
最终结果[索引]。未完成++
}
最终结果[索引]。总计++
}否则{
最后的结果({
日期:元素。日期,
未完成:元素。状态==“未完成”?1:0,
已完成:元素。状态=“已完成”?1:0,
总数:1
})
}
})

console.log(finalResult)
您试图获得想要的结果是什么?@Reyno是的,我一直尝试提取唯一日期,然后匹配状态,但不知何故我被卡住了。此解决方案的运行时间不太理想,特别是对于大型对象。问题是它在循环中使用“filter”函数太频繁地遍历数组。它是O(M*2N+N+M),M是唯一日期的数目。如果性能很重要,请看一看使用O(N+M)的“reduce”解决方案。是的,我知道这一点。因为这个问题看起来很简单,我试着写出最“容易理解”的答案。我计划写一个最佳的解决方案,如果未来我能管理时间。
const final = dates.map(date => {
    const incomplete = arr.filter(a => a.Date == date && a.Status == "incomplete").length
    const complete = arr.filter(a => a.Date == date && a.Status == "Complete").length

    return {
        Date: date,
        Incompleted: incomplete,
        Completed: complete,
        total: complete + incomplete
    }
})