具有计算值,电平转换和新对象创建的Javascript分解

时间:2019-05-01 19:40:42

标签: javascript ecmascript-6 destructuring

我从一个要修饰的api得到一个json响应,并从中创建一个新对象。

const things = [{
    "menu": {
      "id": "file",
      "value": "File",
      "popup": {
        "menuitem": [{
            "value": "3",
            "onclick": "CreateNewDoc()"
          },
          {
            "value": "5",
            "onclick": "OpenDoc()"
          },
          {
            "value": "8",
            "onclick": "CloseDoc()"
          }
        ]
      }
    }
  },
  {
    "menu": {
      "id": "image",
      "value": "Image",
      "popup": {
        "menuitem": [{
            "value": "New",
            "onclick": "CreateNewImage()"
          },
          {
            "value": "Open",
            "onclick": "OpenImage()"
          },
          {
            "value": "Close",
            "onclick": "CloseImage()"
          }
        ]
      }
    }
  }
];

我知道这样做的旧方法:

const chs = [];
things.forEach((e) => {
    const i = {};
    i.Id = e.menu.id;
    i.Value = e.menu.value;
    i.PopupValue = e.menu.popup.menuitem[0].value;
    i.SomethingComputed = e.menu.popup.menuitem[0].value - e.menu.popup.menuitem[1];
    i.ShiftedUp = e.menu.popup.menuitem;
    chs.push(ch);
  });

现在我想使用ES6和解构来做到这一点。但我认为我没有尽我所能,因为我:1)仍然有循环; 2)必须创建这个新对象;和3)需要这些单独的计算线。 我可以使它更紧凑吗?

const chs = [];
things.forEach((e) => {
    const {
        Id: {id},
        Value: {value},
        PopupValue : {menu: {popup} },
    } = e;

    // computed 
    const someComputedValue = Value - PopupValue;

    // new object
    const ch = {
        Id,
        Value,
        SomeComputedValue
    }

    chs.push(ch);
});

4 个答案:

答案 0 :(得分:1)

您可以使用map()而不是forEach(),因此最后不需要执行chs.push()步骤。

您可以将解构直接放在参数列表中,因此不需要分配步骤。这是否更具可读性值得商bat。

如果SomeComputedValue的计算不太复杂,则可以将其直接放在返回的对象中。然后,您可以删除该分配,并可以使用箭头函数的简写形式,该函数仅返回一个值。


const things = [{
    "menu": {
      "id": "file",
      "value": "File",
      "popup": {
        "menuitem": [{
            "value": "3",
            "onclick": "CreateNewDoc()"
          },
          {
            "value": "5",
            "onclick": "OpenDoc()"
          },
          {
            "value": "8",
            "onclick": "CloseDoc()"
          }
        ]
      }
    }
  },
  {},
  {
    "menu": {
      "id": "image",
      "value": "Image",
      "popup": {
        "menuitem": [{
            "value": "New",
            "onclick": "CreateNewImage()"
          },
          {
            "value": "Open",
            "onclick": "OpenImage()"
          },
          {
            "value": "Close",
            "onclick": "CloseImage()"
          }
        ]
      }
    }
  }
];

const chs = things.map(({
menu: {
    id: Id,
    value: Value,
    popup : PopupValue,
} = {id: "defaultID", value: "defaultValue", popup: "defaultPopup"}}) => ({
        Id,
        Value,
        SomeComputedValue: Value - PopupValue
    })
);

console.log(chs);

答案 1 :(得分:1)

非破坏性方式实际上更像是这样:

const chs = things.map(e => ({
  Id: e.menu.id,
  Value: e.menu.value,
  PopupValue: e.menu.popup.menuitem[0].value,
  SomethingComputed: e.menu.popup.menuitem[0].value - e.menu.popup.menuitem[1],
  ShiftedUp: e.menu.popup.menuitem,
}));

解构,或者只是将事物分解为更多变量的一般概念,不必全部或全部:

const chs = things.map(({menu}) => {
  const {menuitem} = menu.popup;

  return {
    Id: menu.id,
    Value: menu.value,
    PopupValue: menuitem[0].value,
    SomethingComputed: menuitem[0].value - menuitem[1],
    ShiftedUp: menuitem,
  };
});

答案 2 :(得分:1)

这不是很漂亮,但是可以使用解构来实现。您可以像这样创建一个箭头函数,该函数可以分解数组中的每个对象并返回一个新对象。然后将其用作对map

的回调

const things=[{menu:{id:"file",value:"File",popup:{menuitem:[{value:"3",onclick:"CreateNewDoc()"},{value:"5",onclick:"OpenDoc()"},{value:"8",onclick:"CloseDoc()"}]}}},{menu:{id:"image",value:"Image",popup:{menuitem:[{value:"New",onclick:"CreateNewImage()"},{value:"Open",onclick:"OpenImage()"},{value:"Close",onclick:"CloseImage()"}]}}}];

const callback = ({
  menu: {
    id: Id,
    value: Value,
    popup: {
      menuitem
    }
  }
}) => ({
  Id,
  Value,
  ShiftedUp: menuitem,
  PopupValue: menuitem[0].value,
  SomethingComputed: menuitem[0].value - menuitem[1].value
})

console.log(things.map(callback))

您甚至可以解构menuitem数组索引以获取前2个value来分隔变量,如下所示:

const callback = ({
  menu: {
    id: Id,
    value: Value,
    popup: {
      menuitem
    },
    popup: {
      menuitem: [
        { value: Value0 },
        { value: Value1 }
      ]
    }
  }
}) => ({
  Id,
  Value,
  ShiftedUp: menuitem,
  PopupValue: Value0,
  SomethingComputed: Value0 - Value1
})

答案 3 :(得分:1)

您无法避免循环,因为things是一个数组,因此必须对其进行迭代。但是,您可以避免使用chs函数创建新对象并推入map数组,因为它实际上为原始数组的每个元素创建了一个新元素,并返回了其中包含新创建的元素或对象的数组案件。因此,在这种情况下,基本上map函数将处理循环和新对象的创建。

此外,您可以将解构操作移至map函数的回调参数,并且可以在返回对象的同时执行计算:

const chs=things.map(({menu:{id,value,popup}}) => ({
        Id: id,
        Value: value,
        PopupValue : popup,
        SomeComputedValue: value+id

    }) 
);

我已经测试了上述结构,它可以为您提供的things数组工作。