javascript中的矩阵数组算法逻辑

问题描述

需要一些帮助来用 javascript 解决这个算法。如何编写考虑时间复杂度的解决方案。考虑到最大key值为3。

input1 = [{0: "small"},{0: "large"}]
output1 = [ 'small.','large.']
-----------------------------------------
input2 = [ {0: "small"},{0: "large"},{1: "red"} ]
output2 = ['small.red','large.red']
-----------------------------------------
input3 = [{0: "small"},{1: "red"},{2:"cake"} ]
output3 = ['small.red.cake','large.red.cake'}
-----------------------------------------
input4 = [{0: "small"},{1: "orange"},{2: "cake"} ]
output4 = ['small.red.cake','large.red.cake','small.orange.cake','large.orange.cake'}
------------------------------------------
input5 = [ {0: "small"},{1: "blue"},{2: "cake"},{2: "ice"}]
output5 = ['small.red.cake','large.orange.cake','small.blue.cake','large.blue.cake','small.red.ice','large.red.ice','small.orange.ice','large.orange.ice','small.blue.ice','large.blue.ice']
] //12 combinations

我的尝试是故意在 if 条件下检查索引。它按预期工作。寻找最佳解决方案。

const input5 = [ {0: "small"},{2: "ice"}]

 let array1 = [];
let array2 = [];
let array3 = [];
input5.forEach(val => {
  if(val[0]) {
    array1.push(val[0]);
  }
  if(val[1]) {
    array2.push(val[1]);
  }
  if(val[2]) {
    array3.push(val[2]);
  }
});
const finalArray = [];
array1.forEach(val1 => {
  if(array2.length > 0) {
     array2.forEach(val2 => {
       if(array3.length > 0) {
         array3.forEach(val3 => {
           const finalVal = `${val1}.${val2}.${val3}`;
           finalArray.push(finalVal);
         })
       }else {
         const finalVal = `${val1}.${val2}`;
         finalArray.push(finalVal);
       }
     })
  }else {
    const finalVal = `${val1}.`;
    finalArray.push(finalVal);
  }
})
console.log(finalArray);

解决方法

您可以使用所需索引处的值构建一个数组数组,并获得格式化的笛卡尔积。

const
    cartesian = array => array.reduce((a,b) => a.reduce((r,v) => r.concat(b.map(w => [].concat(v,w))),[])),format = array => {
        const temp = array.reduce((r,o) => {
            Object.entries(o).forEach(([i,v]) => (r[i] ??= []).push(v));
            return r;
        },[]);

        while (temp.length < 2) temp.push(['']);
        return temp;
    },fn = data => cartesian(format(data)).map(a => a.join('.'));

console.log(fn([{ 0: "small" },{ 0: "large" }]));
console.log(fn([{ 0: "small" },{ 0: "large" },{ 1: "red" },{ 1: "orange" },{ 2: "cake" }]));
.as-console-wrapper { max-height: 100% !important; top: 0; }

,

这种方法有效,但是否符合您的时间复杂度要求,我不知道:

const inputs = [
    [{ 0: "small" },{ 0: "large" }],[{ 0: "small" },{ 1: "red" }],{ 2: "cake" }],{ 1: "blue" },{ 2: "cake" },{ 2: "ice" }],];

function permutate(results,todo) {
    // If we have no layers left to go through,return the results
    if (!todo.length) return results;
    // Get first element of todo and store the rest for later
    const [layer,...rest] = todo;
    // Flatmap that for example with:
    //   results = ['a','b']
    //   layer = [1,2,3]
    //  maps the results into:
    //    [ ['a.1','a.2','a.3'],['b.1','b.2','b.3'] ]
    //  which will then be flattened together.
    results = results.flatMap(result => {
        return layer.map(value => `${result}.${value}`);
    });
    // After that,we permutate the rest of the layers
    return permutate(results,rest);
}

function getCombinations(input) {
    console.log('getCombinations for:',input);
    // Split per layer
    const layers = [];
    for (const obj of input) {
        for (const level in obj) {
            let layer = layers[level];
            if (!layer) layer = layers[level] = [];
            layer.push(obj[level]);
        }
    }
    // Now we have e.g. [ ['small','large'],['red','orange'],['cake','ice'] ]
    console.log('layers:',layers);
    // We immediately pass layer 0 as an array of results
    // then for every other layer,we build upon the (previous) results
    return permutate(layers[0],layers.slice(1));
}

for (const input of inputs) {
    console.log('========');
    const combs = getCombinations(input);
    console.log('combinations:',combs);
}

如果您的输入采用更好的格式,那么性能会更高且更易于编码。

,

相当简洁的解决方案,按键分组,然后在结果的前两个元素上使用修改后的 zip,直到只剩下一个元素,然后 flat() 并返回。

function getOrderedPermutations(arr) {
  const combine = (a,b) => a.flatMap(a_ => b.map(b_ => `${a_}.${b_}`));

  let grouped = Object.values(arr.reduce((a,o) => (
    Object.entries(o).forEach(([k,v]) => (a[k] ??= []).push(v)),a),{})
  );

  let i = grouped.length - 1;
  while (i--) {
    const [a,b,...rest] = grouped;
    grouped = [combine(a,b),...rest];
  }

  return grouped.flat();
}

const inputs = [[{ 0: "small" },];

// Log tests
for (const input of inputs) {
  console.log('---');
  console.log('Input: ',input.map(o => `[${Object.entries(o)[0]}]`).join(','));
  console.log('---');
  console.log(getOrderedPermutations(input),'\n');
}
.as-console-wrapper { max-height: 100% !important; top: 0; }