Array multiplication, as the name suggests, multiplies (combines) each element of multiple arrays. Its result grows with geometric number level, encounter this kind of problem for the first time, often make person’s scalp numb, we solve this problem with JS Angle now.

From an example

It is well known that girls generally need to dress up to go out, so if you have a girlfriend, she has 3 hat, five pieces of clothes, 5 pairs of pants, three pairs of shoes, two lipstick, 4 bags, 2 pair of dark glasses, and mood may affect wearing, she can choose not to bring some items because of in a bad mood, but she will tell you what she would wear, Asked to list all the options, after seeing the title…


const hat = ['a'.'b'.'c'];
const clothes = ['0'.'1'.'2'.'3'.'4'];
const trousers = ['q'.'w'.'e'.'r'.'t'];
const shoes = ['A'.'B'.'C'];
const lipstick = ['$1'.'$2'];
const bag = ['¥1'.'RMB 2'.'¥3'.'¥4'];
const sunglasses = ['^ 1'.'^ 2'];
function getComb(str){
    return arr;
}
Copy the code

solution

Bingbing no matter what the problem, see the array I use the loop idea, to solve the problem, will inevitably meet a lot of problems. If, the topic clearly points out that the girlfriend mood must Max every time go out equipment pull full, that ok no problem, 7 times cycle to solve. But women are obsessed, and you can only list by what she tells you to wear (if you use 7 cycles in any case, forget it).

Random number method

We can just tell the computer to do a random combination, and decide if we’ve already added this result, we don’t need to add it to the array.

const arr = str.split(' ')
    .map(name => {
        switch (name) {
            case 'hat': return hat;
            case 'clothes': return clothes;
            case 'trousers': return trousers;
            case 'shoes': return shoes;
            case 'lipstick': return lipstick;
            case 'bag': return bag;
            case 'sunglasses': returnsunglasses; }})Copy the code

First convert the passed string to a two-dimensional array associated with its passed value, for example: Incoming hat “thanks” arr for [[‘ a ‘, ‘b’, ‘c’], [‘ 0 ‘, ‘1’, ‘2’, ‘3’, ‘4’]], so that we know the number of wear, and the types of wear. It’s not hard to figure out that you can list up to 15 results in this case, define a total variable and modify the code above.

let total = 1;
const arr = str.split(' ')
    .map(name => {
        switch (name) {
            case 'hat': total *= hat.length ; return hat;
            case 'clothes': total *= clothes.length ; return clothes;
            case 'trousers': total *= trousers.length ; return trousers;
            case 'shoes': total *= shoes.length ; return shoes;
            case 'lipstick': total *= lipstick.length ; return lipstick;
            case 'bag': total *= bag.length ; return bag;
            case 'sunglasses': total *= sunglasses.length ; returnsunglasses; }})Copy the code

If we use random numbers we can turn a multiple loop into a for loop judged by a while. We create a new array result, and since we know there are several results, the condition for the while loop is result.length < total.

let result = [], sum = ' ';
    while (result.length < total) {
        for (let i = 0; i < arr.length; i++) {
            sum += arr[i][parseInt(Math.random() * arr[i].length)];
        }
        if (result.indexOf(sum) == -1)
            result.push(sum);
        sum = ' ';
    }
    return result;
Copy the code

Note: math.random () is a random floating-point number that yields a [0,1). The index of the array is an integer, so we need to convert it;sum is a combination of arrays, so we need to restore it after we add it.

Disadvantages of random number methods: The algorithm is too violent, and due to the uncertainty returned by math. random, a lot of time is wasted generating an array of values that have already been added.

The reduce method

We can also use the Reduce method to multiply arrays very easily. Many beginners may be unfamiliar with reduce because it is an uncommon method, but it is very convenient to use reduce. First, a brief introduction to reduce method.

The reduce method accepts a function as an accumulator, and each value in the array (from left to right) begins to shrink to a single value

Reduce executes the callback function for each element in the array, excluding elements that were deleted or never assigned, and takes four arguments: the initial value (or the value returned by the previous callback), the current element value, the current index, and the array that called Reduce.

Arr. Reduce (callback,[initialValue]) callback (a function that executes each value in the array, containing four arguments) previousValue (the value returned from the last callback call, Or initialValue) currentValue (current element in array being processed) Index (index of current element in array) Array (array calling reduce) initialValue (as the first call The first argument to callback.Copy the code

Basic usage

Const a = [6]. const rst = a.reduce((pre,cur)=>{return pre + cur;
    })
    console.log(rst); // rst = 1+2+3+4+5+6
Copy the code

Pre is the first value or the result of the last calculation, there is no initial value passed here, pre defaults to 0,cur is each value of the array. Here is the parsing process:

=> pre = 0 ; cur = a[0]; => pre = 0 + a[0] ; cur = a[1]; => pre = 0 + a[0] + a[1] ; cur = a[2]; . rst = 0 + 1 + 2 + 3 + 4 + 5 + 6 // 21Copy the code

Solve array multiplication with reduce

return arr.reduce((pre,cur)=>{
        return[].concat(... pre.map(e=>cur.map(ele=>ele+e))) })Copy the code

Ex. :

str = 'clothes hat bag';
=> arr :
[ [ '0'.'1'.'2'.'3'.'4' ],
  [ 'a'.'b'.'c' ],
  [ '¥1'.'RMB 2'.'¥3'.'¥4']]Copy the code

Firstly, a complex combinatorial problem is transformed into a superposition combinatorial problem. If we can return the results of arR [0] and ARR [1] to Pre, then we can make a complex combination by pairwise combination. Next use map to do pairwise combinations:

pre : [ '0'.'1'.'2'.'3'.'4' ]
cur : [ 'a'.'b'.'c'] pre.map(e => cur.map(ele => e + ele)); /* first time */ e:'0' , ele: 'a' , e + ele ='0a', pre[['0a']]
e : '0' , ele: 'b' , e + ele = '0b', pre[['0a'.'0b']]... /* End */ pre[['0a'.'0b'.'0c'], ['1a'.'1b'.'1c'], ['2a'.'2b'.'2c'], ['3a'.'3b'.'3c'], ['4a'.'4b'.'4c' ]]
cur : [ '¥1'.'RMB 2'.'¥3'.'¥4' ]
Copy the code

All we need to do is convert the two-dimensional array pre into a one-dimensional array, and the function will multiply the arrays step by step with reduce

[].concat[...pre.map(e => cur.map(ele => e + ele))]
Copy the code

The spread operator (spread) is three points (…) . It is like the inverse of the REST argument, turning an array into a comma-separated sequence of arguments, typically used when passing arguments.

Here we have solved the problem of the girlfriend going out.