JavaScript使用lodash将对象数组转换为另一个对象

Ran*_*ser 5 javascript ecmascript-6 lodash

我有一个看起来像这样的对象数组:

[
  {
    type: 'car',
    choices: [
      'audi',
      'honda',
      'bmw',
      'ford'
    ],
  },
  {
    type: 'drink',
    choices: [
      'soda',
      'water',
      'tea',
      'coffee'
    ],
  },
  {
    type: 'food',
    choices: [
      'chips',
      'pizza',
      'cookie',
      'pasta'
    ],
  }
]
Run Code Online (Sandbox Code Playgroud)

使用lodash如何将其转换为如下所示的内容:

[
  {
    question: [
      {
        drink: "tea"
      },
      {
        car: "bmw"
      }
    ]
  },
  {
    question: [
      {
        food: "cookie"
      },
      {
        car: "ford"
      }
    ]
  },
  {
    question: [
      {
        drink: "soda"
      },
      {
        food: "pizza"
      }
    ]
  },
  {
    question: [
      {
        food: "chips"
      },
      {
        drink: "water"
      }
    ]
  },
  {
    question: [
      {
        car: "audi"
      },
      {
        food: "pasta"
      }
    ]
  },
  {
    question: [
      {
        car: "honda"
      },
      {
        drink: "coffee"
      }
    ]
  },
]
Run Code Online (Sandbox Code Playgroud)

逻辑如下:

  • 每个问题都有两个选择的组合,其中每个选择都是不同类型的示例(汽车和食物)。
  • 不同类型的组合只能出现两次(汽车,食物)。
  • 没有重复的选择。
  • 选择的选择应该是随机的。

我试图使用此函数展平数组

    let flattenItems = _.flatMap(items, ({ type, choices}) =>
      _.map(choices, choice => ({
        question: [
          { type: type, choice: choice },
          { type: type, choice: choice }
        ],
      })
    ));
Run Code Online (Sandbox Code Playgroud)

但这不是我所需要的,也不是随机的。我不确定我的方法是否正确,我想应该使用过滤器或减少

使用JS或lodash来解决此问题的任何帮助都将是不错的。

Nin*_*olz 2

您可以通过检查是否已使用某个值来获得types随机选择的组合。choices

function getCombinations(array, size) {

    function c(left, right) {

        function getQuestion({ type, choices }) {
            var random;
            do {
                random = choices[Math.floor(Math.random() * choices.length)];
            } while (taken.get(type).has(random))
            taken.get(type).add(random);
            return { [type]: random };
        }

        left.forEach((v, i, a) => {
            var temp = [...right, v];
            if (temp.length === size) {
                result.push({ question: temp.map(getQuestion) });
            } else {
                c([...a.slice(0, i), ...a.slice(i + 1)], temp);
            }
        });
    }

    var result = [],
        taken = new Map(array.map(({ type }) => [type, new Set]));

    c(array, []);
    return result;
}

var data = [
    { type: 'car', choices: ['audi', 'honda', 'bmw', 'ford'] },
    { type: 'drink', choices: ['soda', 'water', 'tea', 'coffee'] },
    { type: 'food', choices: ['chips', 'pizza', 'cookie', 'pasta'] }
];

console.log(getCombinations(data, 2));
Run Code Online (Sandbox Code Playgroud)
.as-console-wrapper { max-height: 100% !important; top: 0; }
Run Code Online (Sandbox Code Playgroud)