重命名笛卡尔输出中的对象键

时间:2019-03-14 06:34:06

标签: javascript cartesian-product

对不起,这个问题的标题不好,找不到更好的标题了。

我有以下一系列选择:

const options = [
  {
    display_name: "Size",
    _id: "1",
    values: [
      {
        label: "Small",
        _id: "1"
      },
      {
        label: "Extra Large",
        _id: "2"
      }
    ]
  },
  {
    display_name: "Colors",
    _id: "2",
    values: [
      {
        label: "Red",
        value: "#ff0000",
        _id: "3"
      },
      {
        label: "Green",
        value: "#00ff21",
        _id: "4"
      },
    ]
  }
];

我对此函数运行以获取Cartesian Product

const getCartesian = object => {
  return Object.entries(object).reduce(
    (r, [key, value]) => {
      let temp = [];
      r.forEach(s =>
        (Array.isArray(value) ? value : [value]).forEach(w =>
          (w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
            temp.push(Object.assign({}, s, { [key]: x }))
          )
        )
      );
      return temp;
    },
    [{}]
  );
};

这将导致以下格式的对象数组(console.log输出):


[{0: Object, 1: Object}, {0: Object, 1: Object}, ...]

所需的输出是:

[
            {
               "option":{
                  "id":1,
                  "display_name":"Size"
               },
               "value":{
                  "label":"Small",
                  "id": 1
               }
            },
            {
               "option":{
                  "id":2,
                  "display_name":"Color",
               },
               "value":{
                  "id":5,
                  "label":"Red"
               }
            }
...
]

这是操场,到目前为止我已经尝试过:https://codesandbox.io/s/8nvwm76nnj

2 个答案:

答案 0 :(得分:1)

您需要最后map()才能将数组转换为对象。

const options = [
  {
    display_name: "Size",
    _id: "1",
    values: [
      {
        label: "Small",
        _id: "1"
      },
      {
        label: "Extra Large",
        _id: "2"
      }
    ]
  },
  {
    display_name: "Colors",
    _id: "2",
    values: [
      {
        label: "Red",
        value: "#ff0000",
        _id: "3"
      },
      {
        label: "Green",
        value: "#00ff21",
        _id: "4"
      },
    ]
  }
];

const getCartesian = object => {
      let t = Object.entries(object).reduce(
        (r, [key, value]) => {
          let temp = [];
          r.forEach(s =>
            (Array.isArray(value) ? value : [value]).forEach(w =>
              (w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
                temp.push(Object.assign({}, s, { [key]: x }))
              )
            )
          );
          return temp;
        },
        [{}]
      );
      return t.map(({0:val1,1:val2}) => ({option:val1,arr:val2}))
    };
console.log(getCartesian(options));

答案 1 :(得分:1)

您可以将数组包装在具有属性option的对象中。这样,您以后便可以得到一个数组,其中包含对象,其中option是笛卡尔乘积的键。

const getCartesian = object => {
    return Object.entries(object).reduce(
        (r, [key, value]) => {
            let temp = [];
            r.forEach(s =>
                (Array.isArray(value) ? value : [value]).forEach(w =>
                    (w && typeof w === "object" ? getCartesian(w) : [w]).forEach(x =>
                        temp.push(Object.assign({}, s, { [key]: x }))
                    )
                )
            );
            return temp;
        },
        [{}]
    );
};
const options = [{ display_name: "Size", _id: "1", values: [{ label: "Small", _id: "1" }, { label: "Extra Large", _id: "2" }] }, { display_name: "Colors", _id: "2", values: [{ label: "Red", value: "#ff0000", _id: "3" }, { label: "Green", value: "#00ff21", _id: "4" }] }];

console.log(getCartesian({ option: options }));
.as-console-wrapper { max-height: 100% !important; top: 0; }