前端JS商品规格组合

news2024/11/27 0:46:18

给定一个数组

   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));

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1563042.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java代码审计】XXE漏洞

【Java代码审计】XXE漏洞 1.XXE漏洞概述2.Java中的XML常见接口3.XXE 漏洞审计4.XXE漏洞演示XMLReaderSAXReaderSAXBuilderDocumentBuilder 5.XXE漏洞修复 1.XXE漏洞概述 XXE 为 XML 外部实体注入。当应用程序在解析 XML 输入时,在没有禁止外部实体的加载而导致加载…

AdaBoost算法详解自用笔记(1)二分类问题举例分析

AdaBoost算法详解自用笔记(1)二分类问题举例分析 提升方法的思路 AdaBoost作为一种提升方法,其需要回答两个问题:一是每一轮如何改变训练数据的权重或概率分布;二是如何将弱分类器组合成一个强分类器。对于第一个问题…

Mybatis——一对一映射

一对一映射 预置条件 在某网络购物系统中,一个用户只能拥有一个购物车,用户与购物车的关系可以设计为一对一关系 数据库表结构(唯一外键关联) 创建两个实体类和映射接口 package org.example.demo;import lombok.Data;import …

2024如何做好跨境电商?7个步骤详细讲解

近几年来,随着互联网的发展,国内外的商业贸易越来越流畅,直播电商的火爆也带动着一大批相关的产业链发展,其中跨境电商就是尤为突出的一个。尽管在国内做跨境电商的企业数量非常之多,但仍有许多新人争相入局&#xff0…

Docker搭建LNMP环境实战(09):安装mariadb

1、编写mariadb部署配置文件 在文件夹:/mnt/hgfs/dockers/test_site/compose下创建文件:test_site_mariadb.yml,内容如下: version: "3.5" services:test_site_mariadb:container_name: test_site_mariadbimage: mari…

Android 自定义View 测量控件宽高、自定义viewgroup测量

1、View生命周期以及View层级 1.1、View生命周期 View的主要生命周期如下所示, 包括创建、测量(onMeasure)、布局(onLayout)、绘制(onDraw)以及销毁等流程。 自定义View主要涉及到onMeasure、…

Mybatis-自定义映射ResultMap用法

文章目录 一、处理属性名与字段名不同问题1.通过设置查询别名,使类属性名与字段名(数据库内的名)一致2.设置全局配置,使下划线自动映射为驼峰3.ResultMap 二、处理多对一映射问题前提背景1.使用级联来实现2.association 标签实现3…

Redis数据库常用命令和数据类型

文章目录 一、Redis数据库常用命令1、set/get2、keys3、exists4、del5、type6、rename6.1 重命名6.2 覆盖 7、renamenx8、dbsize9、密码设置10、密码验证11、查看密码12、取消密码13、Redis多数据库常用命令13.1 多数据库间切换13.2 多数据库间移动数据13.3 清除数据库数据 二、…

TSINGSEE青犀智慧工厂视频汇聚与安全风险智能识别和预警方案

在智慧工厂的建设中,智能视频监控方案扮演着至关重要的角色。它不仅能够实现全方位、无死角的监控,还能够通过人工智能技术,实现智能识别、预警和分析,为工厂的安全生产和高效运营提供有力保障。 TSINGSEE青犀智慧工厂智能视频监…

【Leetcode】331. 验证二叉树的前序序列化

文章目录 题目思路代码复杂度分析时间复杂度空间复杂度 结果总结 题目 题目链接🔗 序列化二叉树的一种方法是使用 前序遍历 。当我们遇到一个非空节点时,我们可以记录下这个节点的值。如果它是一个空节点,我们可以使用一个标记值记录&#x…

前端 - 基础 表单标签 - 表单元素 input - (name Value checked maxlength )属性详解

目录 name 属性 Value 属性 Checked 属性 Maxlength 属性 场景问答 # <input> 标签 除了 type 属性外&#xff0c;还有其他常用属性 >>> name 属性 在上一节 我们遇到的 单选按钮 &#xff0c;为什么 本应该 多选一 结果成了 多选多的问题 就…

HashMap考点相关源码解析

参考资料&#xff1a; HashMap超详细源码解析 - 掘金 HashMap常见面试题_hashmap面试题-CSDN博客 详解&#xff1a;HashMap红黑树的阈值为什么是8&#xff1f;_hashmap 红黑树阈值为什么是8-CSDN博客 史上最全HashMap源码整理-CSDN博客 HashMap源码和实现原理_hashmap源码…

10个最佳3D角色下载站

每个人都喜欢免费的东西。 无论是免费的 3D 角色还是游戏资产&#xff0c;我们都喜欢它们。 以下是可以为你的游戏获取免费 3D 角色的前 10 个网站的列表。 你可以将它们用于多种用途&#xff0c;例如 3D 打印或动画剪辑。 如果需要将下载的3D角色转化为其他格式&#xff0c;可…

基于springboot的房屋租赁系统平台

功能描述 流程&#xff1a;房主登陆系统录入房屋信息》发布租赁信息&#xff08;选择房屋&#xff09;》租客登陆系统浏览租赁信息》和房主联系、看房&#xff08;根据租赁信息单的电话线下沟通&#xff09;》房主发起签约&#xff08;生成邀请码&#xff09;》租客登陆系统根…

大模型实时打《街霸》捉对PK,GPT-4居然不敌3.5,新型Benchmark火了

源自&#xff1a;量子位 作者&#xff1a;陈哲涵 黎学臻 考验AI的动态决策力 第一个挑战是定位人物在场景中的位置&#xff0c;通过检测像素颜色来判断。 正如开发者所说&#xff0c;想要赢&#xff0c;要在速度和精度之间做好权衡。 “人工智能技术与咨询” 发布

朵米3.5客服系统源码,附带系统搭建教程

朵米客服系统是一款全功能的客户服务解决方案&#xff0c;提供多渠道支持&#xff08;如在线聊天、邮件、电话等&#xff09;&#xff0c;帮助企业建立与客户的实时互动。该系统具有智能分流功能&#xff0c;可以快速将客户请求分配给适当的客服人员&#xff0c;提高工作效率。…

RabbitMQ高级笔记

视频链接&#xff1a;【黑马程序员RabbitMQ入门到实战教程】 文章目录 1.发送者的可靠性1.1.生产者重试机制1.2.生产者确认机制1.3.实现生产者确认1.3.1.开启生产者确认1.3.2.定义ReturnCallback1.3.3.定义ConfirmCallback 2.MQ的可靠性2.1.数据持久化2.1.1.交换机持久化2.1.2.…

Python疑难杂症(14)---Numpy知识集合(二)学习Python的NUMpy模块的定向取值、聚合分析函数、矩阵运算等

4、索引取值 像对 python 列表那样进行切片&#xff0c;对 NumPy 数组进行任意的索引和切片&#xff0c;取得数组或者单个的元素值。 arr1np.array([1,2,3,4,5,6,7]) print(arr1) print(arr1[5]) print(arr1[2:4]) 输出&#xff1a;[1 2 3 4 5 6 7] 6 [3 4] B np.arra…

如何分析现货白银的行情?2个工具的介绍

现在给投资者拿出一段现货白银行情&#xff0c;投资者会如何分析&#xff1f;怎么找到其中的机会呢&#xff1f;相信有不少人对此还是不甚了解。有的投资者平常看书学得头头是道&#xff0c;但是一碰到实际行情就懵了&#xff0c;这都是没有好好掌握如何分析现货白银行情的方法…

VScode debug python(服务器)

方法一&#xff1a; 创建launch.json文件&#xff1a; launch.json文件地址&#xff1a; launch.json文件内容&#xff1a; {"version": "0.2.0", //指定了配置文件的版本"configurations": [{"name": "Python: Current File&…