讲师中心 微信公众号

工具推荐

视频效率加速
Laper
Laper

剧本策划到成片协作

Seko
Seko

AI短剧一键生成成片

AniShort
AniShort

AI短剧协同制作平台

updream

一键生成高质量推广成片

生成支持条件约束的多维数组笛卡尔积

陌墨酱_1550

陌墨酱_1550

发布时间:2026-01-12 09:24:35

|

356人浏览过

|

来源于php中文网

原创

生成支持条件约束的多维数组笛卡尔积

本文介绍如何在 javascript 中实现带条件限制的笛卡尔积运算,支持基于参数索引和值的动态规则(如“当第 0 列为 2 时,第 1 列只能取 'a' 或 'b'”),通过预编译谓词函数 + 过滤策略高效生成合法组合。

在实际开发中,尤其是配置生成、参数化测试或表单联动场景,我们常需枚举多个维度的合法组合,但并非所有笛卡尔积结果都有效——某些参数值之间存在业务约束(例如:选择“iOS”系统时,版本号仅允许 15–17;选择“Android”时则只允许 11–14)。此时,一个支持条件过滤的笛卡尔积生成器就至关重要。

下面提供一种清晰、可扩展且性能可控的实现方案:

Android Control
Android Control

通过命令行工具(uiautomator、screencap、input、am)控制安卓设备。优先尝试非 root 执行,失败后自动回退至 root...

下载

✅ 核心思路:分离计算与约束

  • 第一步:用纯函数式 cartesian 高效生成全部基础组合(不带任何逻辑);
  • 第二步:将 pairRestrictions 对象解析为一组谓词函数(predicate functions),每个函数接收一个组合数组 xs,返回 true 表示该组合满足该项约束;
  • 第三步:对全量结果调用 .filter(),仅保留通过所有谓词检验的组合。

? 实现代码(ES6+,无依赖)

// 递归式笛卡尔积(尾递归优化版,支持任意长度数组)
const cartesian = ([xs, ...xss]) => {
  const kids = xs && cartesian(xss);
  return xs == undefined 
    ? [[]] 
    : xs.flatMap(x => kids.map(ys => [x, ...ys]));
};

// 主函数:生成带条件约束的组合
const generateCombinations = (params, pairRestrictions) => {
  // 将嵌套 restrictions 转换为谓词函数数组
  const predicates = Object.entries(pairRestrictions).flatMap(
    ([k0, v0]) => Object.entries(v0).flatMap(
      ([k1, v1]) => Object.entries(v1).flatMap(
        ([k2, v2]) => (xs) => 
          xs[Number(k0)] == k1 ? v2.includes(xs[Number(k2)]) : true
      )
    )
  );

  // 生成全量组合并过滤
  return cartesian(params).filter(combination => 
    predicates.every(predicate => predicate(combination))
  );
};

? 使用示例

const params = [[1, 2, 3], ["A", "B", "C"], [10, 11, 12]];
const pairRestrictions = { 0: { 2: { 1: ["A", "B"] } } };

const result = generateCombinations(params, pairRestrictions);
console.log(result.length); // → 24(原 27 组中排除了 [2,'C',*] 和 [3,'C',*] 共 3 组)
✅ 注意:上述约束含义为:若第 0 个参数取值为 2,则第 1 个参数必须属于 ["A","B"]。由于 pairRestrictions[0][2] 显式定义了 2 的约束,而 1 和 3 未声明,因此默认允许任意值(即谓词返回 true)。

⚠️ 关键注意事项

  • 键类型限制:pairRestrictions 中除最内层数组外的所有键(如 0、2、1)均作为对象属性名使用,因此必须是字符串或可隐式转为字符串的值(如数字、Symbol)。不支持对象、函数、null 或 undefined 作为键。
  • 语义明确性:当前实现采用 “全满足(AND)”逻辑(.every())。若需“任一满足(OR)”逻辑(如“满足任一规则即可”),请将 .every() 替换为 .some()。
  • 性能权衡:该方案先生成全量再过滤,在参数维度高、约束稀疏时可能内存开销较大。如需极致性能(如百万级组合),建议改用回溯式增量生成(边构建边校验),但代码复杂度显著上升。
  • 扩展建议:可进一步支持更丰富的约束语法,例如区间 [min, max]、正则 /^v\d+$/、甚至自定义函数 (val) => val > 0 && val % 2 === 0,只需统一谓词生成逻辑即可。

✅ 总结

本方案以函数式思维解耦“组合生成”与“条件验证”,结构清晰、易于调试与扩展。它不侵入原始笛卡尔积逻辑,而是通过高阶函数组合实现关注点分离,既保持了算法的通用性,又赋予其强大的业务适配能力——真正做到了「用数据描述规则,用函数执行逻辑」。

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

UpDream
UpDream Hot

一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

VibeKnow
VibeKnow Hot

一款AI视频创作工具,主要用于全球首个AI知识视频创作平台,文档、文章、网页,一键生成视频,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

Flowith
Flowith Hot

Flowith是一款基于画布和智能体工作流的 AI 协作工作空间。

花生AI
花生AI Hot

一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

305

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

406

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

395

2025.12.24

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

569

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1698

2024.03.01

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1938

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3184

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6384

2023.10.24

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

20

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
WebStorm 官方调试文档
WebStorm 官方调试文档

共0课时 | 0人学习

React 教程
React 教程

共58课时 | 12.5万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 6.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn