Ramda.js:合并两个具有相同属性ID的对象数组

6

我有这两个对象数组

todos: [
    {
      id: 1,
      name: 'customerReport',
      label: 'Report send to customer'
    },
    {
      id: 2,
      name: 'handover',
      label: 'Handover (in CRM)'
    },
  ]

并且:

todosMoreDetails: [
          {
            id: 1,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: []
          },
          {
            id: 2,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: []
          }
        ]

因此,最终的对象数组将基于对象ID组合两者,如下所示:

FinalTodos: [
          {
            id: 1,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: [],
            name: 'customerReport',
            label: 'Report send to customer'
          },
          {
            id: 2,
            checked: false,
            link: {
              type: 'url',
              content: 'http://something.com'
            },
            notes: [],
            name: 'handover',
            label: 'Handover (in CRM)'
          }
        ]

我尝试使用mergemergeAllmergeWithKey,但可能还缺少某些内容。

2个回答

12

您可以通过使用一个中间的groupBy来实现这一点:

使用groupBy将todosMoreDetails数组转换为以todo属性ID为键的对象:

var moreDetailsById = R.groupBy(R.prop('id'), todosMoreDetails);

moreDetailsById是一个对象,其中键为id,值是待办事项数组。如果id是唯一的,则这将是一个单例数组:

{
      1: [{
        id: 1,
        checked: false,
        link: {
          type: 'url',
          content: 'http://something.com'
        },
        notes: []
      }]
}

现在通过将每个待办事项合并到从分组视图中检索到的详细信息中,转换todos数组:

var finalTodos = R.map(todo => R.merge(todo, moreDetailsById[todo.id][0]), todos);

另一种更详细的方法:

function mergeTodo(todo) {
   var details = moreDetailsById[todo.id][0]; // this is not null safe
   var finalTodo = R.merge(todo, details);
   return finalTodo;
}

var moreDetailsById = R.groupBy(R.prop('id'), todosMoreDetails);
var finalTodos = todos.map(mergeTodo);

它起作用了!但我不知道为什么。您能简要解释一下吗?那太好了。 - Anonymous
1
我对我的建议增加了一些细节。 - J O

-4

我猜合并只用于数组。搜索对象“extend”。也许将待办事项细节存储在单独的对象中是更好的解决方案。

使用underscore:

var result = [];
var entry = {};
_.each(todos, function(todo) {
    _.each(todosMoreDetails, function(detail) {
        if (todo.id == detail.id) {
            entry = _.extend(todo, detail);
            result.push(entry);
        }
    }
});
return result;

OP在标题中标记了ramdajs,说明这个问题与ramdajs相关。 - Jared

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接