【问题标题】:looping through two arrays and left join循环遍历两个数组并左连接
【发布时间】:2018-01-16 16:48:39
【问题描述】:

我有两个数组,第一个包含工作流的各个阶段:

const workflow_stages = ["Draft", "Kick-Off", "Phase 1", "Phase 2", "Complete"];

第二个包含某些工作流阶段的任务:

const tasks = [{workflow_stage: "Kick-Off",
             tasks: ["Assignment1", "Assignment2", "Assignment3"]},
            {workflow_stage: "Phase 2",
             tasks: ["Phase2_Assignment1", "Phase2_Assigment2"]}]

我如何遍历这两个数组并拥有一个组合数组,其中列出了所有工作流阶段(无论是否有任务)及其相关任务(有点像左连接):

const combined = [{workflow_stage: "Draft",
                tasks: []},
               {workflow_stage: "Kick-Off",
                tasks: ["Assignment1", "Assignment2", "Assignment3"]},
               {workflow_stage: "Phase 1",
                tasks: []},
               {workflow_stage: "Phase 2",
                tasks: ["Phase2_Assignment1", "Phase2_Assigment2"]},
               {workflow_stage: "Complete",
                tasks: []}]

【问题讨论】:

  • 你能让你的代码真正有效吗?
  • 我不明白“任务”和“组合”之间的区别 - 任务看起来与组合相同。
  • 你只需要遍历workflow_stages并查看tasks变量上是否有与之关联的任务,如果没有,则返回空任务。

标签: javascript arrays loops object


【解决方案1】:

您可以将所有任务收集到一个对象中,然后将所有workflow_stage 映射到具有阶段和任务的对象。

var workflow_stages = ['Draft', 'Kick-Off', 'Phase 1', 'Phase 2', 'Complete'],
    tasks = [{ workflow_stage: 'Kick-Off', tasks: ['Assignment1', 'Assignment2', 'Assignment3'] }, { workflow_stage: 'Phase 2', tasks: ['Phase2_Assignment1', 'Phase2_Assigment2'] }],
    collection = Object.create(null),
    result;

tasks.forEach(function (item) {
    collection[item.workflow_stage] = (collection[item.workflow_stage] || []).concat(item.tasks);
});

result = workflow_stages.map(function (workflow_stage) {
    return {
        workflow_stage: workflow_stage,
        task: collection[workflow_stage] || []
    };
});
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6 与 Map

var workflow_stages = ['Draft', 'Kick-Off', 'Phase 1', 'Phase 2', 'Complete'],
    tasks = [{ workflow_stage: 'Kick-Off', tasks: ['Assignment1', 'Assignment2', 'Assignment3'] }, { workflow_stage: 'Phase 2', tasks: ['Phase2_Assignment1', 'Phase2_Assigment2'] }],
    collection = new Map,
    result;

workflow_stages.forEach(workflow_stage => collection.set(workflow_stage, { workflow_stage, tasks: [] }));

tasks.forEach(({ workflow_stage, tasks }) => collection.get(workflow_stage).tasks.push(...tasks));

result = [...collection.values()];
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    【解决方案2】:

    您可以使用array#maparray#find。遍历workflow_stages 数组并为每个值检查tasks 数组中的对象。如果对象存在则返回该对象,否则创建一个新对象并返回它。

    var workflow_stages = ['Draft', 'Kick-Off', 'Phase 1', 'Phase 2', 'Complete'],
        tasks = [{ workflow_stage: 'Kick-Off', tasks: ['Assignment1', 'Assignment2', 'Assignment3'] }, { workflow_stage: 'Phase 2', tasks: ['Phase2_Assignment1', 'Phase2_Assigment2'] }],
        result = workflow_stages.map(workflow_stage => {
            var task = tasks.find(o => o['workflow_stage'] === workflow_stage);
            return task ? task : {workflow_stage, tasks : []};
        });
        
    console.log(result);

    【讨论】:

      猜你喜欢
      • 2020-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-10
      • 1970-01-01
      • 2020-12-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多