当前位置: 首页 > news >正文

前端JS商品规格组合

给定一个数组

   let data = [{name: "颜色",specs: ["白色", "黑色"],},{name: "尺寸",specs: ["14寸","15寸", "16寸"],},{name: "处理器",specs: ["i5", "i7", "i9"],},];

组合处理(据说这套路叫什么啥笛卡尔积)

方法很巧妙,自己写不一定写的出,但是可以借鉴前人的经验,然后去试着理解,分析,即使写不出也要能看的懂,如果完成任务直接拿现成的方法用也无妨

function combine(arr) {let result = [[]];//定义一个数组必须要有一项(且这一项必须是数组)arr.map((x) => {let res = [];console.log(result,'result');result.map((y) => {x.specs.map((z) => {//最内层循环x.specs.map第一次执行完之后res的值就是[["白色"], ["黑色"]],因为specs的值为两项["白色", "黑色"]循环两遍,循环完后跳出循环到上一层循环,//此时上一层的循环result.map的result还是[[]],所以执行完一遍之后跳出当前循环到上一层循环,//此时arr.map循环完第一遍开始赋值将result = res,此时result为[["白色"], ["黑色"]],然后开始进入result.map循环//此时x.specs.map的值为arr.map的第二次循环也就是循环["14寸","15寸", "16寸"],而result.map为[["白色"], ["黑色"]],//此时循环的步骤为result.map第一遍循环result,此时y为["白色"],而z为arr第二项的specs里面的每一项,于是用["白色"]去拼接["14寸","15寸", "16寸"]的每一项//此时就res就变成了result.map[["白色"], ["黑色"]]跟["14寸","15寸", "16寸"]去按顺序一项一项的去组合,组合完之后将 result = res,//以此类推便出现了最终的所有值的组合结果,很巧妙的一个套路,自己去从0开始写还是比较费脑筋的,尤其逻辑处理能力尚不强的时候以及没多少经验的时候res.push([...y, z]);});});result = res;//将第一次循环之后的值赋值给result,此时result为[["白色"], ["黑色"]],故下一波循环得循环两次});return result;}console.log(combine(data));

逻辑解释(给自己看的),配合打印的值看更容易理解

//最内层循环x.specs.map第一次执行完之后res的值就是[["白色"], ["黑色"]],因为specs的值为两项["白色", "黑色"]循环两遍,循环完后跳出循环到上一层循环,

            //此时上一层的循环result.map的result还是[[]],所以执行完一遍之后跳出当前循环到上一层循环,

            //此时arr.map循环完第一遍开始赋值将result = res,此时result为[["白色"], ["黑色"]],然后开始进入result.map循环

            //此时x.specs.map的值为arr.map的第二次循环也就是循环["14寸","15寸", "16寸"],而result.map为[["白色"], ["黑色"]],

            //此时循环的步骤为result.map第一遍循环result,此时y为["白色"],而z为arr第二项的specs里面的每一项,于是用["白色"]去拼接["14寸","15寸", "16寸"]的每一项

            //此时就res就变成了result.map[["白色"], ["黑色"]]跟["14寸","15寸", "16寸"]去按顺序一项一项的去组合,组合完之后将 result = res,

            //以此类推便出现了最终的所有值的组合结果,很巧妙的一个套路,自己去从0开始写还是比较费脑筋的,尤其逻辑处理能力尚不强的时候以及没多少经验的时候

 

方法二:递归调用

这个方法稍微理解起来有点绕

    const generateCombinations = (arr, result = [], current = {}, i = 0)=>{// 由于arr.length的长度一般都不会等于,所以最开始直接执行else// 第二次函数调用i等于1,而数组长度依旧为3,所以还是执行else// 第三次函数调用,此时i等于2,数组长度依旧为3,所以还是执行else// 第四次函数调用,此时i等于3,i已经等于数组长度了,故执行if,此时current为,i5 {颜色: '白色', 尺寸: '14寸', 处理器: 'i5'},// 当第四次函数调用完之后执行return result,但是函数之前的循环并没有终止掉,上一步的循环停留在调用递归的地方// 而此时函数执行到处理器规格的specs循环的第二遍,此时current等于i7 {颜色: '白色', 尺寸: '14寸', 处理器: 'i7'},i还是之前的没有加一的i所以为2// 于是再次执行又要递归i再次加1等于3// 后面就不解释了,直接看打印值,很巧妙的一种方法,理解起来稍微有点绕不如笛卡尔积写法if (i === arr.length) {console.log('执行push');result.push({...current});} else {for (const value of arr[i].specs) {// 第一次循环(此处第一次循环为颜色规格的specs第一次循环)current[arr[i].name]的arr[i].name值为:'颜色',而value为颜色规格的每一项,// 此时循环第一次之后arr不变,result不变,current为 白色 {颜色: '白色'},i+1等于1,然后执行递归// 第二次循环,由于执行了递归,第二次循环变成了循环尺寸规格的specs,// 此时current为 14寸 {颜色: '白色', 尺寸: '14寸'},i+1等于2,然后再次递归,// 第三次循环,由于执行了递归,第三次循环变成了循环处理器规格的specs,// 此时current为 i5 {颜色: '白色', 尺寸: '14寸', 处理器: 'i5'},i+1等于3,然后再次递归,current[arr[i].name] = value;console.log(arr[i].name,'----',value,current,i);generateCombinations(arr, result, current, i + 1);}}return result;}console.log(generateCombinations(data));

 

相关文章:

前端JS商品规格组合

给定一个数组 let data [{name: "颜色",specs: ["白色", "黑色"],},{name: "尺寸",specs: ["14寸","15寸", "16寸"],},{name: "处理器",specs: ["i5", "i7", "i9&…...

⾃定义类型:联合和枚举

乐观学习,乐观生活,才能不断前进啊!!! 我的主页:optimistic_chen 我的专栏:c语言 点击主页:optimistic_chen和专栏:c语言, 创作不易,大佬们点赞鼓…...

Spring IOC控制反转、DI注入以及配置

1.使用xml的方式进行配置IOC容器&#xff0c;首先引入依赖 在Resource资源下配置&#xff0c;applicationContext.xml ,刷新mevan后可以直接选择配置spring.xml文件 <!-- spring核心用来管理bean --><dependency><groupId>org.springframework</g…...

RabbitMQ的部分模式

1发布订阅模式 发送者 package org.example; import com.alibaba.fastjson.JSON; import com.rabbitmq.client.BuiltinExchangeType; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Connection; import com.rabbitmq.client.ConnectionFactory; import ja…...

提取单选框的值,并通过ajax传值到后台

<!DOCTYPE html> <html lang"zh" xmlns:th"http://www.thymeleaf.org" xmlns:shiro"http://www.pollix.at/thymeleaf/shiro"> <head><th:block th:include"include :: header(日库存更新提示)" /> </head&…...

Django创建多app应用

目录 1. 引言 2. 多app创建的两种方式 2.1 多个app结构 2.2 单个apps多个app 3. 最后 1. 引言 在平常业务开发中&#xff0c;我们遇到的功能可能会有很多&#xff0c;单个app的应用可能无法满足我们 这个时候&#xff0c;我们就需要多app应用&#xff0c;例如&#xff1a…...

如何反反爬虫

我们来讲最常见的反反爬虫方法 import requests r requests.get(网页网址) print(r.requests.headers) 一.使用简单的方法把请求头改为真的浏览器模式 import requests link网页地址 heraders{User-Agent:} rrequests.get(link,headersheaders) print(r.requsts.headers)我们…...

wireshark抓包之DNS协议

DNS协议 DNS协议的主要作用是将域名解析为对应的IP地址。当我们在浏览器中输入一个网址时&#xff0c;计算机需要通过DNS协议来查找该网址对应的IP地址&#xff0c;以便能够建立连接并访问目标资源。 DNS协议的工作流程大致如下&#xff1a; 用户的计算机或设备&#xff08;充…...

升级到 Java 21 是值得的

升级到 Java 21 是值得的 又到了一年中的这个时候——New Relic 的年度“State of the Java Ecosystem”调查结果出来了&#xff0c;我一如既往地深入研究了它。虽然我认为该报告做得很好并且提出了很好的问题&#xff0c;但我对有多少 Java 开发人员正在使用低版本感到沮丧。…...

C# 多线程

文章目录 C# 多线程进程与线程无参数的子线程带参数的子线程运行结果 销毁线程 Abort()运行结果 ThreadPool和Task运行结果 异步与同步运行结果 lock单线程运行结果 多线程运行结果 使用lock运行结果 C# 多线程 进程与线程 进程&#xff1a;进程就是一个应用程序&#xff0c;…...

快速安装sudachipy日语包

1、前往 https://rustup.rs 下载并安装 Rustup Linux系统可直接运行以下命令 Window系统需要去网站下载exe包 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh2、安装 Rust 编译器 rustup install stable3、设置默认版本 rustup default stable4、重新安装 …...

蓝桥杯刷题day13——乘飞机【算法赛】

一、问题描述 等待登机的你看着眼前有老有小长长的队伍十分无聊&#xff0c;你突然想要知道&#xff0c;是否存在两个年龄相仿的乘客。每个乘客的年龄用一个 0 到 36500 的整数表示&#xff0c;两个乘客的年龄相差 365 以内就认为是相仿的。 具体来说&#xff0c;你有一个长度…...

大模型量化技术-BitsAndBytes

Transformers 量化技术 BitsAndBytes bitsandbytes是将模型量化为8位和4位的最简单选择。 8位量化将fp16中的异常值与int8中的非异常值相乘,将非异常值转换回fp16,然后将它们相加以返回fp16中的权重。这减少了异常值对模型性能产生的降级效果。4位量化进一步压缩了模型,并且…...

EasyExcel 复杂表头的导出(动态表头和静态表头)

问题&#xff1a;如图&#xff0c;1部分的表头是动态的根据日期变化&#xff0c;2部分是数据库对应的字段&#xff0c;静态不变的&#xff1b; 解决方案&#xff1a;如果不看1的部分&#xff0c;2部分内容可以根据实体类注解的方式导出&#xff0c;那么我们是不是可以先将动态表…...

centos7 fatal error: curl/curl.h: No such file or directory

若编译遇到此问题&#xff0c;可以查看环境是否libcurl库 yum list installed | grep libcurl 发现未安装libcurl库 执行libcurl库的安装命令&#xff1a; 1.对于Debian/Ubuntu系统&#xff1a; sudo apt-get install libcurl4-openssl-dev 2.对于RHEL/CentOS系统&#xf…...

【Linux】自定义协议+序列化+反序列化

自定义协议序列化反序列化 1.再谈 "协议"2.Cal TCP服务端2.Cal TCP客户端4.Json 喜欢的点赞&#xff0c;收藏&#xff0c;关注一下把&#xff01; 1.再谈 “协议” 协议是一种 “约定”。在前面我们说过父亲和儿子约定打电话的例子&#xff0c;不过这是感性的认识&a…...

常见故障排查和优化

一、MySQL单实例故障排查 故障现象 1 ERROR 2002 (HY000): Cant connect to local MySQL server through socket /data/mysql/mysql.sock (2) 问题分析&#xff1a;以上情况一般都是数据库未启动或者数据库端口被防火墙拦截导致。 解决方法&#xff1a;启动数据库或者防火墙…...

选择华为HCIE培训机构有哪些注意事项

选择软件培训机构注意四点事项1、口碑&#xff1a;学员和社会人士对该机构的评价怎样&#xff1f; 口碑对于一个机构是十分重要的&#xff0c;这也是考量一个机构好不好的重要标准&#xff0c;包括社会评价和学员的评价和感言。誉天作为华为首批授权培训中心&#xff0c;一直致…...

python怎么处理txt

导入文件处理模块 import os 检测路径是否存在&#xff0c;存在则返回True&#xff0c;不存在则返回False os.path.exists("demo.txt") 如果你要创建一个文件并要写入内容 #如果demo.txt文件存在则会覆盖&#xff0c;并且demo.txt文件里面的内容被清空&#xff0c;如…...

SAMRTFORMS 转换PDF 发送邮件

最终成果&#xff1a; *&---------------------------------------------------------------------**& Report ZLC_FIND_EXIT*&---------------------------------------------------------------------**&根据T-CODE / 程序名查询出口、BADI增强*&-------…...

装饰模式(Decorator Pattern)重构java邮件发奖系统实战

前言 现在我们有个如下的需求&#xff0c;设计一个邮件发奖的小系统&#xff0c; 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式&#xff08;Decorator Pattern&#xff09;允许向一个现有的对象添加新的功能&#xff0c;同时又不改变其…...

Cinnamon修改面板小工具图标

Cinnamon开始菜单-CSDN博客 设置模块都是做好的&#xff0c;比GNOME简单得多&#xff01; 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

linux 下常用变更-8

1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行&#xff0c;YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID&#xff1a; YW3…...

Caliper 配置文件解析:config.yaml

Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...