在不使用递归函数的情况下获取所有可能的组合

时间:2018-07-25 14:26:18

标签: javascript loops for-loop recursion

options.yearoptions.monthoptions.day可以具有值'numeric''twoDigit'

   const differentOptions = ['numeric', 'twoDigit'];
   const options = {
     year: '', month: '', day: '',
   };

我想使用所有可能的组合而不使用递归的列表。

我知道有2个循环的可能性,但是我不知道该怎么做。

预期产量

应该是这8种组合:

year: 'numeric',  month: 'numeric',  year: 'numeric'

year: 'twoDigit', month: 'numeric',  year: 'numeric'

year: 'numeric',  month: 'twoDigit', year: 'numeric'

year: 'numeric',  month: 'numeric',  year: 'twoDigit'

year: 'twoDigit', month: 'twoDigit', year: 'numeric'

year: 'numeric',  month: 'twoDigit', year: 'twoDigit'

year: 'twoDigit', month: 'numeric',  year: 'twoDigit'

year: 'twoDigit', month: 'twoDigit', year: 'twoDigit'

这就是我尝试过的

   const differentOptions = [numeric, twoDigit];
   const dateAttributes = ['year', 'month', 'day']
   const options = {
     year: '', month: '', day: '',
   };

   for (let i = 0; i < 3; i++) {
     for (let j = 0; j < differentOptions.length; j++) {
       options[dateAttributes[i]] = differentOptions[j];
     }
     console.log(options);
   }

2 个答案:

答案 0 :(得分:1)

不是两个循环,2 ** 3 = 8,您可以这样写:

const answer = [];
const differentOptions = ['numeric', 'twoDigit'];
differentOptions.forEach((el) => {
    differentOptions.forEach((el1) => {
        differentOptions.forEach((el2) => {
            answer.push({
                year: el,
                month: el1,
                day: el2
            })
        })
    })
});
console.log(answer)

答案 1 :(得分:0)

由于总是有两个潜在值,因此可以将其视为二进制数的计数问题。您的每种组合都恰好对应一个三位数的二进制数字(如果您有更多类别,则为更多)。例如:

001 = { year: 'numeric', month: 'numeric', day: 'twoDigit' } 010 = {年:“数字”,月:“ twoDigit”,天:“数字”}`

这样您就可以算到n ** 2,其中n是您拥有的键数:

const differentOptions = ['numeric', 'twoDigit'];
const options = [ 'year', 'month','day']

for (let d = 1; d < 2 ** options.length; d++ ){
    let option_mask = Array.from(d.toString(2).padStart(options.length, '0'))
    let r = option_mask.reduce((a, c, i) => (a[options[i]] = differentOptions[c], a), {})
    console.log(r)
}

这可能不是最有效的方法,但它是思考和理解问题的有趣方法。这是一个通用的解决方案-如果您要添加其他类别,则无需更改任何内容:

const differentOptions = ['numeric', 'twoDigit'];

// Add minute to get 16 combinations
const options = [ 'year', 'month','day', 'minute']

for (let d = 1; d < 2 ** options.length; d++ ){
    let option_mask = Array.from(d.toString(2).padStart(options.length, '0'))
    let r = option_mask.reduce((a, c, i) => (a[options[i]] = differentOptions[c], a), {})
    console.log(r)
}