根据另一个对象中的属性向对象添加属性数组

时间:2018-08-17 15:58:49

标签: javascript arrays algorithm object

我正在处理大量对象。通过过滤,我缩小了数据集。我需要基于另一个“查找”对象中的属性向每个对象添加属性数组。我最初的对象数组看起来像这样。

const arr = [{id: "12345", type: "square", current: "0", max: "1", code: "50"}, 
             {id: "23456", type: "square", current: "0", max: "3", code: "50"},
             {id: "54321", type: "square", current: "2", max: "4", code: "50"},
             {id: "54321", type: "circle", current: "0", max: "1", code: "100"}, 
             {id: "65432", type: "circle", current: "3", max: "3", code: "100"},
             {id: "76543", type: "circle", current: "0", max: "2", code: "100"}]

我有一个“查找”对象。该对象的基础是每个typecode都有一个level 0到3。对于上面的每个对象,我需要为每个{添加一个title属性从idtype匹配codecurrent的{​​1}}。在此示例中,我简化了“查找”对象。

max

所以我得到的对象数组看起来像这样

const lookup = [{title: "yes", code: "50", level: "0", type: "square"},
                {title: "no", code: "50", level: "1", type: "square"}, 
                {title: "maybe", code: "50", level: "2", type: "square"},
                {title: "sure", code: "50", level: "3", type: "square"},
                {title: "up", code: "100", level: "0", type: "circle"},
                {title: "down", code: "100", level: "1", type: "circle"},
                {title: "left", code: "100", level: "2"}, type: "circle"},
                {title: "right", code: "100", level: "3"}, type: "circle"}]

是否有一种优雅的方法可以执行此操作而无需遍历const result = [{id: "12345", type: "square", current: "0", max: "1", code: "50", titles: ["yes", "no"]}, {id: "23456", type: "square", current: "0", max: "3", code: "50", titles: ["yes", "no", "maybe", "sure"]}, {id: "54321", type: "square", current: "2", max: "4", code: "50", titles: ["maybe", "sure"]}, {id: "54321", type: "circle", current: "0", max: "2", code: "100", titles: ["up", "down"]}, {id: "65432", type: "circle", current: "3", max: "3", code: "100", titles: ["right"]}, {id: "76543", type: "circle", current: "0", max: "2", code: "100", titles: ["up", "down", "left"]}] typecode的每个单独的组合?

1 个答案:

答案 0 :(得分:1)

首先,让我们将lookup数组转换为嵌套树,这样标题的查找将非常简单:

const lookupTree = lookup.reduce((acc, o) => {
    var byType = acc[o.type] = acc[o.type] || {};
    var byCode = byType[o.code] = byType[o.code] || {};
    byCode[o.level] = o.title;
    return acc;
}, {});

这将导致这样的树结构:

{
   "square": {
      "50": {
         "0": "yes",
         "1": "no",
         "2": "maybe",
         "3": "sure"
      }
   },
   "circle": {
      "100": {
         "0": "up",
         "1": "down",
         "2": "left",
         "3": "right"
      }
   }
}

现在,对于数组arr中的每个对象,我们只需简单地遍历上方的树,就可以从current循环到max(包括)并将每个级别映射到其等效标题按类型,然后按代码,最后按级别(我们首先检查那些对象是否存在,即查找树中当前对象的类型,是否有代码以及是否也有级别):

arr.forEach(o => {
    o.titles = [];
    for(var i = o.current; i <= o.max; i++) {
        if(lookupTree[o.type] && lookupTree[o.type][o.code] && lookupTree[o.type][o.code][i]) {
            o.titles.push(lookupTree[o.type][o.code][i]);
        }
    }
});

示例:

const arr = [{"id":"12345","type":"square","current":"0","max":"1","code":"50"},{"id":"23456","type":"square","current":"0","max":"3","code":"50"},{"id":"54321","type":"square","current":"2","max":"4","code":"50"},{"id":"54321","type":"circle","current":"0","max":"1","code":"100"},{"id":"65432","type":"circle","current":"3","max":"3","code":"100"},{"id":"76543","type":"circle","current":"0","max":"2","code":"100"}];
const lookup = [{"title":"yes","code":"50","level":"0","type":"square"},{"title":"no","code":"50","level":"1","type":"square"},{"title":"maybe","code":"50","level":"2","type":"square"},{"title":"sure","code":"50","level":"3","type":"square"},{"title":"up","code":"100","level":"0","type":"circle"},{"title":"down","code":"100","level":"1","type":"circle"},{"title":"left","code":"100","level":"2","type":"circle"},{"title":"right","code":"100","level":"3","type":"circle"}];

const lookupTree = lookup.reduce((acc, o) => {
    var byType = acc[o.type] = acc[o.type] || {};
    var byCode = byType[o.code] = byType[o.code] || {};
    byCode[o.level] = o.title;
    return acc;
}, {});

arr.forEach(o => {
    o.titles = [];
    for(var i = o.current; i <= o.max; i++) {
        if(lookupTree[o.type] && lookupTree[o.type][o.code] && lookupTree[o.type][o.code][i]) {
            o.titles.push(lookupTree[o.type][o.code][i]);
        }
    }
});

console.log(arr);

注意:如果您不想更改原始数组arr,则只需使用map而不是forEach并克隆对象,然后再添加他们的title属性。