Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JavaScript transform array of objects into another using lodash

I have an array of objects that looks like this:

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

Using lodash how to transform it into something that looks like this:

[
  {
    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"
      }
    ]
  },
]

The logic is as follow:

  • Every question has a combination of 2 choices where every choice is of different type example (car and food).
  • Combination of different types should occur only twice (car, food).
  • No duplication of choices.
  • The selection of choices should be randomized.

I tried to Flatten the array using this function

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

but it's not what I need, and it's not random. I not sure my approach is the correct one, I'm thinking I should use a filter or reduce

Any help on how to solve this would be appreciated using JS or lodash would be good.

like image 575
RandomUser Avatar asked Jun 05 '19 11:06

RandomUser


People also ask

How do I merge two arrays in Lodash?

If you want to merge or combine multiple arrays, string, numbers into a single array using lodash then you can use its _. concat() method. const str = 50; const arr1 = [20]; const arr2 = [30, 35]; const arr3 = [[10]] const final_arr = _.

What does Lodash flatten do?

The Lodash. flatten() method is used to flatten the array to one level deep. Parameter: This method accepts single parameter array that holds simple array or array of arrays. Return Value: The return type of this function is array.

What is Lodash merge?

Lodash's `merge()` Function Given two objects destination and source , Lodash's merge() function copies the 2nd object's own properties and inherited properties into the first object.

How do you sort an array of objects in Lodash?

The _. sortBy() method creates an array of elements which is sorted in ascending order by the results of running each element in a collection through each iteratee. And also this method performs a stable sort which means it preserves the original sort order of equal elements.


1 Answers

You could get a combination from types and a random choices selecten with a check if a value is aleady used.

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));
.as-console-wrapper { max-height: 100% !important; top: 0; }
like image 93
Nina Scholz Avatar answered Oct 07 '22 20:10

Nina Scholz