for和findIndex循环的替代选项?

时间:2019-11-24 17:15:25

标签: javascript node.js

我当前正在使用forfindIndex更新主要result变量中的总计。有没有其他方法可以重写它,使其更短或更易读?

const payload = [
        { Id: 1, Total: 5 },
        { Id: 3, Total: 2 },
]

const result = {
    Items: [
        { Id: 1, Name: 'Item 1 A', Total: 1, Type: "Main"},
        { Id: 1, Name: 'Item 1 B', Total: 0},
        { Id: 2, Name: 'Item 2 C', Total: 1, Type: "Main"},
        { Id: 2, Name: 'Item 2 D', Total: 0},
        { Id: 3, Name: 'Item 3 E', Type: "Main"},
        { Id: 3, Name: 'Item 3 F', Total: 0},
    ]
}

for(const itemPayload of payload) {
    const itemIndex = result.Items.findIndex(item => item.Id === itemPayload.Id && item.Type === "Main");
    
    if (itemIndex !== -1) {
        result.Items[itemIndex].Total = itemPayload.Total;
    }
}

console.log(result);

4 个答案:

答案 0 :(得分:2)

在这里,我们创建一个Map,然后循环访问它。它更干净,更易读。

const payload = [
  { Id: 1, Total: 5 },
  { Id: 3, Total: 2 },
]

const result = {
  Items: [
    { Id: 1, Name: 'Item 1 A', Total: 1, Type: "Main" },
    { Id: 1, Name: 'Item 1 B', Total: 0 },
    { Id: 2, Name: 'Item 2 C', Total: 1, Type: "Main" },
    { Id: 2, Name: 'Item 2 D', Total: 0 },
    { Id: 3, Name: 'Item 3 E', Type: "Main" },
    { Id: 3, Name: 'Item 3 F', Total: 0 },
  ]
};


const payloadMap = payload.reduce((map, obj) => {
  map[obj.Id] = obj.Total;
  return map;
}, {});

result.Items = result.Items.map(item => {
  if (item.Type === 'Main' && payloadMap[item.Id]) {
    item.Total = payloadMap[item.Id];
  }
  return item;
});

console.log(result);

答案 1 :(得分:1)

您可以将有效负载转换为Map,然后仅循环result.Items一次(而不是通过findIndex重复一次):

const payloadMap = new Map(payload.map(({Id, Total}) => [Id, Total]));
for (const item of result.Items) {
    if (item.Type === "Main") {
        const total = payloadMap.get(item.Id);
        if (total !== undefined) {
            item.Total = total;
        }
    }
}

实时示例:

const payload = [
        { Id: 1, Total: 5 },
        { Id: 3, Total: 2 },
]

const result = {
    Items: [
        { Id: 1, Name: 'Item 1 A', Total: 1, Type: "Main"},
        { Id: 1, Name: 'Item 1 B', Total: 0},
        { Id: 2, Name: 'Item 2 C', Total: 1, Type: "Main"},
        { Id: 2, Name: 'Item 2 D', Total: 0},
        { Id: 3, Name: 'Item 3 E', Type: "Main"},
        { Id: 3, Name: 'Item 3 F', Total: 0},
    ]
}

// Convert the payload to a Map:
const payloadMap = new Map(payload.map(({Id, Total}) => [Id, Total]));

// Loop through `result.Items` just once:
for (const item of result.Items) {
    if (item.Type === "Main") {
        const total = payloadMap.get(item.Id);
        if (total !== undefined) {
            item.Total = total;
        }
    }
}

console.log(result);

地图针对随机访问检索进行了优化。

另一种选择是,除了type = "Main"中的项数组之外,还具有result项的映射,它们均引用同一对象,但是这意味着当您向/从中添加/删除时数组,您还必须从地图中添加/删除。

答案 2 :(得分:1)

如果您正在寻找这样的东西,可以尝试这样的事情。

const payload = [{
    Id: 1,
    Total: 5
  },
  {
    Id: 3,
    Total: 2
  },
]

const result = {
  Items: [{
      Id: 1,
      Name: 'Item 1 A',
      Total: 1,
      Type: "Main"
    },
    {
      Id: 1,
      Name: 'Item 1 B',
      Total: 0
    },
    {
      Id: 2,
      Name: 'Item 2 C',
      Total: 1,
      Type: "Main"
    },
    {
      Id: 2,
      Name: 'Item 2 D',
      Total: 0
    },
    {
      Id: 3,
      Name: 'Item 3 E',
      Type: "Main"
    },
    {
      Id: 3,
      Name: 'Item 3 F',
      Total: 0
    },
  ]
}


let newdata = result.Items.map(ele => {

  if (ele.Type == "Main") {
    let payload_ = payload.find(e => e.Id == ele.Id);
    if (payload_) {

      ele.Total = payload_.Total;

    }

  }
  return ele;

})

console.log(newdata);

答案 3 :(得分:1)

您可以使用find()方法来获得选择条件的第一个匹配项,并使用o.hasOwnProperty('Total') && obj.Id === o.Id)作为选择条件:

    const payload = [
            { Id: 1, Total: 5 },
            { Id: 3, Total: 2 },
    ]
    
    const result = {
        Items: [
            { Id: 1, Name: 'Item 1 A', Total: 1, Type: "Main"},
            { Id: 1, Name: 'Item 1 B', Total: 0},
            { Id: 2, Name: 'Item 2 C', Total: 1, Type: "Main"},
            { Id: 2, Name: 'Item 2 D', Total: 0},
            { Id: 3, Name: 'Item 3 E', Type: "Main"},
            { Id: 3, Name: 'Item 3 F', Total: 0},
        ]
    }
    
    payload.forEach(obj => result.Items.find(o => (o.hasOwnProperty('Total') && obj.Id === o.Id)).Total = obj.Total) 
    
    
    console.log(result);