javascript—按状态将TODO数组缩减为包含三个对象的对象

goucqfw6  于 2021-09-23  发布在  Java
关注(0)|答案(7)|浏览(303)

我有一个数组,我试图得到一个包含三个对象的对象, todo , completeddeleted .

const todos = [{
       id: 'a',
       name: 'Buy dog',
       action: 'a',
       status: 'deleted',
     },
     {
       id: 'b',
       name: 'Buy food',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'c',
       name: 'Heal dog',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'd',
       name: 'Todo this',
       action: 'd',
       status: 'completed',
     },
     {
       id: 'e',
       name: 'Todo that',
       action: 'e',
       status: 'todo',
     },
   ];

todos.reduce((acc, todo) => {
  console.log(acc);
  return {
    ...acc,
    [todo.status]: { ...acc[todo.status], ...todo }
  };
}, {});

我遇到的问题是,我只得到最近的“完成”项目。有人能帮我指出哪里出了问题吗?
结果如下:

{
  "deleted": [
    {
      "id": "a",
      "name": "Buy dog",
      "action": "a",
      "status": "deleted"
    }
  ],
  "completed": [
    {
      "id": "b",
      "name": "Buy food",
      "tooltip": null,
      "status": "completed"
    },
    {
      "id": "c",
      "name": "Heal dog",
      "tooltip": null,
      "status": "completed"
    },
    {
      "id": "d",
      "name": "Todo this",
      "action": "d",
      "status": "completed"
    }
  ],
  "todo": [
    {
      "id": "e",
      "name": "Todo that",
      "action": "e",
      "status": "todo"
    }
  ]
}
uidvcgyl

uidvcgyl1#

很接近,但需要将修改后的对象设置为新变量。此外,由于存在多个“已完成”数组,因此可能需要聚合数组。这首先创建基础对象,然后使用 reduce() 对于这两种行为

let keys=todos.reduce((b,a) => ({...b, [a.status]:[]}),{}), 
    revised = todos.reduce((b, todo) => {
    b[todo.status].push(todo);
     return b;
    }, keys);
const todos = [{
       id: 'a',
       name: 'Buy dog',
       action: 'a',
       status: 'deleted',
     },
     {
       id: 'b',
       name: 'Buy food',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'c',
       name: 'Heal dog',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'd',
       name: 'Todo this',
       action: 'd',
       status: 'completed',
     },
     {
       id: 'e',
       name: 'Todo that',
       action: 'e',
       status: 'todo',
     },
   ];

let keys=todos.reduce((b,a) => ({...b, [a.status]:[]}),{}), 
revised = todos.reduce((b, todo) => {
b[todo.status].push(todo);
 return b;
}, keys);

  console.log(revised);
4c8rllxm

4c8rllxm2#

你的问题不是很清楚,我想你想要的输出 {todo: [], completed: [], deleted: []} .
在这种情况下,这里有一个简单的解决方案。

var todos = [{
    id: 'a',
    name: 'Buy dog',
    action: 'a',
    status: 'deleted',
  },
  {
    id: 'b',
    name: 'Buy food',
    tooltip: null,
    status: 'completed',
  },
  {
    id: 'c',
    name: 'Heal dog',
    tooltip: null,
    status: 'completed',
  },
  {
    id: 'd',
    name: 'Todo this',
    action: 'd',
    status: 'completed',
  },
  {
    id: 'e',
    name: 'Todo that',
    action: 'e',
    status: 'todo',
  },
];

var result = todos.reduce(function(result, item) {
  var statusList = result[item.status];
  if (!statusList) {
    statusList = [];
    result[item.status] = statusList;
  }
  statusList.push(item);
 // or use this to create a deep copy
 // statusList.push(JSON.parse(JSON.stringify(item)));
  return result;
}, {});

console.log(result);
xytpbqjk

xytpbqjk3#

const todos = [{id: 'a',name: 'Buy dog',action: 'a',status: 'deleted'},{id: 'b',name: 'Buy food',tooltip: null,status: 'completed'},{id: 'c',name: 'Heal dog',tooltip: null,status: 'completed'},{id: 'd',name: 'Todo this',action: 'd',status: 'completed'},{id: 'e',name: 'Todo that',action: 'e',status: 'todo'}];

const result = todos.reduce((acc, todo) => {
  return {
    ...acc,
    [todo.status]: acc[todo.status]
     ? [...acc[todo.status], { ...acc[todo.status], ...todo }] 
     : [todo]
  };
}, {});

console.log(result)

不确定这个结果是否是你想要的。基本上,最后我们将有一个状态为key的对象,该值将是一个充当分组的数组

q3qa4bjr

q3qa4bjr4#

function getByValue(arr, value) {
    var result  = arr.filter(function(o){return o.status == value;} );
    return result? result[0] : null; // or undefined
}

todo_obj = getByValue(arr, 'todo')
deleted_obj = getByValue(arr, 'deleted')
completed_obj = getByValue(arr, 'completed')
pxyaymoc

pxyaymoc5#

您的代码很好,只需要使用reduce函数作为输出-它不会发生变化 todos 它返回一个新值。

const todos = [{id: 'a',name: 'Buy dog',action: 'a',status: 'deleted',},{id: 'b',name: 'Buy food',tooltip: null,status: 'completed',},{id: 'c',name: 'Heal dog',tooltip: null,status: 'completed',},{id: 'd',name: 'Todo this',action: 'd',status: 'completed',},{id: 'e',name: 'Todo that',action: 'e',status: 'todo',},];

const out = todos.reduce((acc, todo) => {
  return {
    ...acc,
    [todo.status]: { ...acc[todo.status], ...todo }
  };
}, {});

console.log(out);
.as-console-wrapper {min-height:100%} /* make preview prettier */
7bsow1i6

7bsow1i66#

你可以分组 status 通过破坏 todo 以及调用(扩展)先前的值或使用带有空合并运算符的新数组( ?? ). 如果您的js版本不支持该操作符,您可以使用逻辑or( || ).

const todos = [
  { id: 'a' , name: 'Buy dog'   , action: 'a'   , status: 'deleted'   },
  { id: 'b' , name: 'Buy food'  , tooltip: null , status: 'completed' },
  { id: 'c' , name: 'Heal dog'  , tooltip: null , status: 'completed' },
  { id: 'd' , name: 'Todo this' , action: 'd'   , status: 'completed' },
  { id: 'e' , name: 'Todo that' , action: 'e'   , status: 'todo'      }
];

const grouped = todos.reduce((acc, { status, ...rest }) => ({
  ...acc,
  [status]: [...(acc[status] ?? []), { ...rest, status }]
}), {});

console.log(grouped);
.as-console-wrapper { top: 0; max-height: 100% !important; }
izkcnapc

izkcnapc7#

您只能从原始数组中获取最近完成的元素,因为结果中的每个对象都是对象,而不是数组。。。从一个简单的foreach开始,而不是reduce,可能更容易看出这是否满足了您的需要:

const todos = [{
       id: 'a',
       name: 'Buy dog',
       action: 'a',
       status: 'deleted',
     },
     {
       id: 'b',
       name: 'Buy food',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'c',
       name: 'Heal dog',
       tooltip: null,
       status: 'completed',
     },
     {
       id: 'd',
       name: 'Todo this',
       action: 'd',
       status: 'completed',
     },
     {
       id: 'e',
       name: 'Todo that',
       action: 'e',
       status: 'todo',
     },
   ];
let res = {}
todos.forEach(todo => {
  res[todo.status]=res[todo.status]||[]
  res[todo.status].push(todo)
})
console.log(res)

相关问题