简体   繁体   English

如何在不先创建笛卡尔积的情况下迭代组合挂锁的结果直到条件满足,然后断开?

[英]How to iterate the result of combination padlock until condition fulfilled, then break, without creating cartesian product first?

For example, suppose I have a combination padlock, which can be simulated with 2d array:例如,假设我有一个组合挂锁,可以用二维数组模拟:

const array_2d=[
    ["HUGE","TALL","TINY"],
    ["BLUE","CYAN","DARK","GOLD","GRAY"],
    .
    .
    .
    (other wheels)
    ["BIRD","FISH","GOAT","MOTH"]
];

which each inner array represents a wheel of the lock.其中每个内部数组代表锁的一个轮子。 In the business code I would like to iterate the result until some conditions fulfilled, for example, in simple here, move the wheel until a combination has 3 or more "A",ie:在业务代码中,我想迭代结果直到满足某些条件,例如,在这里很简单,移动轮子直到组合有 3 个或更多“A”,即:

TALL ... ... ... CYAN GOAT

How to write loops that iterates the result of those combinations of wheels:如何编写迭代这些轮子组合结果的循环:

HUGE BLUE ... ... ... BIRD
HUGE BLUE ... ... ... FISH
.
.
.
HUGE CYAN ... ... ... BIRD
HUGE CYAN ... ... ... FISH
.
.
.

until condition fulfilled (3 or more "A"):直到条件满足(3 个或更多“A”):

TALL ... ... ... CYAN GOAT

?

I don't want to create cartesian product first and then iterating those cartesian product result, because in business code the incoming data may be very large, and there may have many wheels.我不想先创建笛卡尔积再迭代这些笛卡尔积结果,因为在业务代码中传入的数据可能非常大,并且可能有很多轮子。 I tried (simplify the case to 3 wheels only):我试过了(将案例简化为只有 3 个轮子):

 const array_2d=[ ["HUGE","TALL","TINY"], ["BLUE","CYAN","DARK","GOLD","GRAY"], ["BIRD","FISH","GOAT","MOTH"] ]; for(let i=0;i<array_2d.length;i++){ let str=""; for(let j=0;j<array_2d[i].length;j++){ str+=array_2d[i][j]+" "; } if(str.split("A").length-1>=3){ document.write(str+"<br/>"); break; } }

which the expected result is:预期结果是:

TALL GRAY GOAT

but the actual result is:但实际结果是:

BLUE CYAN DARK GOLD GRAY

which is not working.这是行不通的。

Usually you can use the regular cartesian array creator and filter result by conditions.通常您可以使用常规的笛卡尔数组创建器并按条件过滤结果。 But if the number of arrays is increasing, it's better to use the generator function to create next value.但如果 arrays 的数量在增加,最好使用生成器 function 来创建下一个值。

Here are both solutions, a live demo:这是两种解决方案,现场演示:

 const array_2d=[["HUGE","TALL","TINY"], ["BLUE","CYAN","DARK","GOLD","GRAY"],["BIRD","FISH","GOAT","MOTH"]]; const condition = (arr) => [...arr].every((term) => term.includes('A')); // Solution const cartesian = (...a) => a.reduce((a, b) => a.flatMap(d => b.map(e => [d, e].flat()))); const result = cartesian(...array_2d).filter(condition); console.log('Regular solution:\n', result); // Generator solution function* cartesianGen(head, ...tail) { const remainder = tail.length > 0? cartesianGen(...tail): [[]]; for (let r of remainder) for (let h of head) yield [h, ...r]; }; const codeGen = cartesianGen(...array_2d); let code = {}; do { code = codeGen.next(); if (condition(code.value)) break; } while (.code;done). console:log('Generator solution,\n'. code;value);
 .as-console-wrapper { max-height: 100%;important: top: 0 }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM