js——数据操作——实现阶梯价格排序——基础积累

最近在写网络报价的时候,遇到一个需求,就是要根据采购数量,找到符合数量的阶梯区间,并找到最便宜的采购价格。

比如下面:

let originViewList = [
	{
		id:1,
		incrementalQuantity:10,
		priceList:[
			{
				minQuantity:1,
				price:20
			},
			{
				minQuantity:1,
				price:18
			},
			{
				minQuantity:300,
				price:17
			}
		]
	}
]

上面数据中的incrementalQuantity是增长量,minQuantity是阶梯数,比如采购的数量是200,则可以选择minQuantity为1的,然后增长量是10的,这样,200 = 1+1020;则最后的采购量是201。如果选择minQuantity为300,则最低采购量只能是300了。两者价格比较:20120与300*17相比较,还是选择minQuantity为1的采购价格更低,而且minQuantity为1的价格为18的采购价更低,所以最后选择的是{minQuantity:1,price:18}的一组。

所以要实现的效果:

1.根据阶梯数+增长量:获取最终的采购量,阶梯数低于采购量的,需要配合增长量。阶梯数高于采购量的,直接使用阶梯数作为采购量
2.如果阶梯数有相同的,则需要找个价格最低的

下面是我的解决思路:

解决步骤1:根据采购量找到介于哪两个阶梯价之间

findNearestNumber(arr, target){
    return arr.reduce((pre, curr) => {
        return Math.abs(pre - target) > Math.abs(curr - target) ? curr : pre;
    })
},

使用方法:

let numArr = [1,1,20,30];
let num = 12;
let nearNum = this.findNearestNumber(numArr, num);
let nearIndex = numArr.indexOf(nearNum);
if (numArr[nearIndex] > num) {
    nearIndex = nearIndex - 1 > -1 ? nearIndex - 1 : 0;
}
console.log(nearIndex);

在这里插入图片描述
也就是说12最接近的索引是1,也就是介于索引1到索引2之间。
在这里插入图片描述
再看下数量是2的,最接近的索引是0,索引1也是最接近的,这种相同阶梯数的后面有处理。

解决步骤2:根据阶梯数+增长量获取最终的采购量

let arr = originViewList[0].priceList;
let resultNum = Math.ceil((num - arr[nearIndex].minQuantity) / this.originViewList[index].incrementalQuantity) * this.originViewList[index].incrementalQuantity + arr[nearIndex].minQuantity;
console.log('numArr', numArr, nearIndex, resultNum);

上面数据中的incrementalQuantity是增长量,minQuantity是阶梯数,比如采购的数量是200,则可以选择minQuantity为1的,然后增长量是10的,这样,200 = 1+10*20;则最后的采购量是201。如果选择minQuantity为300,则最低采购量只能是300了。

解决步骤3:如果阶梯数有相同,则需要根据价格排序,找最低价的

//如果有数量相同的情况
let eqIndexArr = [];
numArr.forEach((n, nIndex) => {
    if (n == numArr[nearIndex]) {
        eqIndexArr.push(nIndex);
    }
})
if (eqIndexArr.length > 1) {
    let eqPriceArr = [];
    eqIndexArr.forEach((eq) => {
        eqPriceArr.push({ index: eq, price: arr[eq].price });
    })
    const sortBy = (field) => {
        return function (a, b) {
            return a[field] - b[field];
        };
    }
    let maxArr = eqPriceArr.sort(sortBy('price'));//对象数组根据price价格字段升序排列
    this.OptimalIndex[index] = maxArr[0].index;
    res = resultNum * maxArr[0].price;//采购量*最低价格
}

解决步骤4:如果没有相同阶梯价的,则直接计算

//当前阶梯价*采购量与下一个的最小数量*价格相比较,谁的采购价低,选择谁
if (resultNum * arr[nearIndex].price < arr[nearIndex + 1].minQuantity * arr[nearIndex + 1].price) {
    this.OptimalIndex[index] = nearIndex;
    res = resultNum * arr[nearIndex].price;
} else {
    this.OptimalIndex[index] = nearIndex + 1;
    res = arr[nearIndex + 1].minQuantity * arr[nearIndex + 1].price;
}

上面的两种情况都能拿到最终的采购总价了。下面根据采购总价进行排序:

//sortLevel  是升序还是降序的判断
priceSort(num) {
    var _that = this;
    this.viewList.forEach((item, index) => item.Index = index);
    this.originViewList = JSON.parse(JSON.stringify(this.viewList));
    if (this.viewList.length == 1) {
        _that.findPriceListPrice(this.viewList[0].priceList, num, this.viewList[0].Index);
    } else {
        this.viewList.sort(function (a, b) {
            //找index  a.priceList   b.priceList
            var aPrice = _that.findPriceListPrice(a.priceList, num, a.Index);
            var bPrice = _that.findPriceListPrice(b.priceList, num, b.Index);
            return !_that.sortLevel ? (aPrice - bPrice) : (bPrice - aPrice);
        })
    }
},

合并代码记录:
最终代码记录:

priceSort(num) {
    var _that = this;
    this.viewList.forEach((item, index) => item.Index = index);
    this.originViewList = JSON.parse(JSON.stringify(this.viewList));
    if (this.viewList.length == 1) {
        _that.findPriceListPrice(this.viewList[0].priceList, num, this.viewList[0].Index);
    } else {
        this.viewList.sort(function (a, b) {
            //找index  a.priceList   b.priceList
            var aPrice = _that.findPriceListPrice(a.priceList, num, a.Index);
            var bPrice = _that.findPriceListPrice(b.priceList, num, b.Index);
            return !_that.sortLevel ? (aPrice - bPrice) : (bPrice - aPrice);
        })
    }
},
findPriceListPrice(arr, num, index) {
   var res = 99999999;
   let numArr = arr.map(a => a.minQuantity);
   if (!num) {
       res = 99999999;
   } else {
       let nearNum = this.findNearestNumber(numArr, num);
       let nearIndex = numArr.indexOf(nearNum);
       if (numArr[nearIndex] > num) {
           nearIndex = nearIndex - 1 > -1 ? nearIndex - 1 : 0;
       }
       let resultNum = Math.ceil((num - arr[nearIndex].minQuantity) / this.originViewList[index].incrementalQuantity) * this.originViewList[index].incrementalQuantity + arr[nearIndex].minQuantity;
       console.log('numArr', numArr, nearIndex, resultNum);
       if (nearIndex < arr.length - 1) {
           //如果有数量相同的情况
           let eqIndexArr = [];
           numArr.forEach((n, nIndex) => {
               if (n == numArr[nearIndex]) {
                   eqIndexArr.push(nIndex);
               }
           })
           if (eqIndexArr.length > 1) {
               let eqPriceArr = [];
               eqIndexArr.forEach((eq) => {
                   eqPriceArr.push({ index: eq, price: arr[eq].price });
               })
               const sortBy = (field) => {
                   return function (a, b) {
                       return a[field] - b[field];
                   };
               }
               let maxArr = eqPriceArr.sort(sortBy('price'));
               this.OptimalIndex[index] = maxArr[0].index;
               res = resultNum * maxArr[0].price;
           } else {
               if (resultNum * arr[nearIndex].price < arr[nearIndex + 1].minQuantity * arr[nearIndex + 1].price) {
                   this.OptimalIndex[index] = nearIndex;
                   res = resultNum * arr[nearIndex].price;
               } else {
                   this.OptimalIndex[index] = nearIndex + 1;
                   res = arr[nearIndex + 1].minQuantity * arr[nearIndex + 1].price;
               }
           }
       } else {
           this.OptimalIndex[index] = nearIndex;
           res = resultNum * arr[nearIndex].price;
       }
   }
   return res;
},
findNearestNumber(arr, target){
   return arr.reduce((pre, curr) => {
       return Math.abs(pre - target) > Math.abs(curr - target) ? curr : pre;
   })
},

上面的代码逻辑其实是有问题的,最正确的解决办法就是:根据每一个的阶梯数,获取最终的采购量,然后与各自的价格相乘,找最低的作为最终的采购价。

这样才是最正确的。

下面附上最正确的解决办法:

findPriceListPrice(list, num, index) {
  var res = 99999999;
  let arr = JSON.parse(JSON.stringify(list));
  arr && arr.forEach((a, aIndex) => {
      a.index = aIndex;
  })
  console.log('arr', arr);
  if (!num) {
      res = 99999999;
  } else {
      arr && arr.forEach(item => {
          if (item.minQuantity < num) {
              item.resultNum = Math.ceil((num - item.minQuantity) / this.originViewList[index].incrementalQuantity) * this.originViewList[index].incrementalQuantity + item.minQuantity;
          } else {
              item.resultNum = item.minQuantity;
          }
          item.totalPrice = item.resultNum * item.price;
      })
      const sortBy = (field) => {
          return function (a, b) {
              return a[field] - b[field];
          };
      }
      let maxArr = arr.sort(sortBy('totalPrice'));
      console.log('maxArr', maxArr);
      this.OptimalIndex[index] = maxArr[0].index;
      res = maxArr[0].totalPrice;
  }
  return res;
},

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

el-upload上传图片,视频可获取视频时长。

对element-ui组件的upload组件再一次封装&#xff0c;简单记录。下面是效果图。 注意点&#xff1a;该组件现在仅支持单图和单个视频上传。 <template><div :style"myStyle"><divclass"uploads":style"{width: upWith px,height: up…

零门槛微调大模型:基于 Ludwig 低代码框架使用 LoRA 技术微调实践

一、Ludwig 介绍 自然语言处理 (NLP) 和人工智能 (AI) 的飞速发展催生了许多强大的模型&#xff0c;它们能够理解和生成如同人类般的文本&#xff0c;为聊天机器人、文档摘要等应用领域带来了革命性的改变。然而&#xff0c;释放这些模型的全部潜力需要针对特定用例进行微调。…

我用通义千问做了个银从初级法规考试答题AI助手

我用通义千问做了个银从初级法规考试答题AI助手 起因方法&#xff1a;创建方法&#xff1a;微调成果展示 起因 多选考试实在太难了&#xff0c;惨不忍睹的正确率&#xff0c;博主我就想有一个专门刷多选的工具&#xff0c;但找了半天没找到。然后就想到用通义试试&#xff0c;…

MySQL 服务无法启动

常见原因: 检查端口占用&#xff1a; 使用命令行工具&#xff08;如netstat&#xff09;来检查3306端口是否已被其他程序占用,输入netstat -ano&#xff08;Windows&#xff09;或netstat -tulnp | grep 3306&#xff08;Linux/Mac&#xff09;来查找3306端口的占用情况。如果…

excel转pdf并且加水印,利用ByteArrayOutputStream内存流不产生中间文件

首先先引入包&#xff1a;加水印和excel转PDF的 <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.12</version></dependency><dependency><groupId>org.apache.poi&l…

【Numpy】深入解析numpy.diag()函数

numpy.diag()&#xff1a;深入探索NumPy库中的对角矩阵操作 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f3…

统计绘图:基于matplotlib包绘制双轴图

本文介绍通过 Python的matplotlib包 绘制 双轴图&#xff08;Dual Y-Axis Plot&#xff09;&#xff0c;即双 y 轴图&#xff0c;又称双纵坐标图。 这类图表的主要用途是显示两个具有不同数值范围的变量在同一 x 轴上的 变化趋势&#xff0c;从而便于比较和分析。&#xff08;…

docker中安装jenkins,并在node和cloud上跑通基于源码控制SCM的pipeline

目录 一、摘要 二、部署和使用 1. docker部署jenkins 1.1 准备数据目录 1.2 拉取jenkins镜像并启动 1.3 初始化配置 1.3.1 登录容器查看初始化密码 1.3.2 访问jenkins并输入初始化密码 1.3.3 创建管理员账户 1.3.4 初始化完成 2. jenkins使用之多分支流水线 2.1 准…

大模型落地竞逐,云计算大厂“百舸争流”

作者 | 辰纹 来源 | 洞见新研社 从ChatGPT到Sora&#xff0c;从图文到视频&#xff0c;从通用大模型到垂直大模型……经过了1年多时间的探索&#xff0c;大模型进入到以落地为先的第二阶段。 行业的躁动与资本的狂热相交汇&#xff0c;既造就了信仰派的脚踏实地&#xff0c;也…

适用于当下的红色系统可视化大屏,大量图。

特定场合下使用红色系可视化大屏是可以的&#xff0c;但是千万要注意时间和场合&#xff0c;平时最好别用。

获取支持Windows7的最新Edge离线版本

从110版本开始&#xff0c;微软Edge和谷歌停止了对Win7、Win8/8.1的支持&#xff0c;后续又发布了几版安全更新&#xff0c;截止目前为止&#xff0c;能支持Win7的版本是 109.0.1518.140。 如果你想用最新版本谷歌浏览器&#xff0c;可以考虑下Supermium&#xff0c;这个浏览器…

内存马实战(持续更新中)

注&#xff1a;这篇文章记录在我的语雀里面&#xff0c;语雀格式好看一点&#xff0c;地址&#xff1a; https://ganmaocai.yuque.com/ghgp8x/zoy1yn/faet35ae9gpxzn61 计划 复现以下框架的内存马注入&#xff1a; shiro&#xff1a; 普通内存马 冰蝎马 WebSocket马 xxl-job…

C++ 计时器

文章目录 一、简介二、实现代码2.1 windows平台2.2 C标准库 三、实现效果 一、简介 有时候总是会用到一些计时的操作&#xff0c;这里也整理了一些代码&#xff0c;包括C标准库以及window自带的时间计算函数。 二、实现代码 2.1 windows平台 StopWatch.h #ifndef STOP_WATCH_H…

JWT的详解

一.什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应用间安全地传递信息。它是一种紧凑的、自包含的方式&#xff0c;用于在用户和服务之间以 JSON 对象的形式安全地传输信息。 JWT 主要由三部分…

计算机系统基础 7 分支程序的实现

简单条件转移指令 根据单个标志位的值&#xff08;CF&#xff0c; SF&#xff0c;OF&#xff0c;PF&#xff0c;ZF&#xff09;来确定是否转移&#xff0c; 如果条件成立&#xff0c;则&#xff08;EIP&#xff09; 位移量 ➡ EIP&#xff0c;否则什么也不做。 注意&#xff0…

c# 将数据库连接字符串写到配置文件中,及获取

考虑到代码的安全性&#xff0c;已经修改起来的方便性&#xff0c;我们常常不会将数据库连接字符串直接放在代码中&#xff0c;而是将这个字符串放到一个App.config配置文件中&#xff0c;赋值给一个变量&#xff0c;然后再在代码中引用这个变量。 具体做法如下: ①展开项目名称…

微星笔记本618爆款推荐清单,好评有礼活动火热进行中

微星笔记本618爆款推荐清单&#xff0c;好评有礼活动火热进行中 又是一年一度的618大促&#xff0c;作为电子数码产品的主场&#xff0c;准备选购笔记本的消费者早已翘首以盼有更实惠的价格~ 不负期待&#xff0c;微星笔记本携多款性价比爆款笔记本、Claw掌上游戏机&#xff0…

Google Find My Device:科技守护,安心无忧

在数字化的时代&#xff0c;我们的生活与各种智能设备紧密相连。而 Google Find My Device 便是一款为我们提供安心保障的实用工具。 一、Find My Decice Netword的定义 谷歌的Find My Device Netword旨在通过利用Android设备的众包网络的力量&#xff0c;帮助用户安全的定位所…

记录一个更新adobe软件导致加载PDF文件异常的问题

最近由于项目需要,没有办法把原有的adobe正版软件进行了卸载,换了个盗版软件,结果导致我的pdf文件加载的时候出现异常。 报错的语句是这个 string str = System.Environment.CurrentDirectory; // string fileName = MyOpenFileDialog(); axAcroPDF1.LoadFile(…

abs(-2147483648) == 2147483648?

从数学意义上&#xff0c;这是对的。但是&#xff0c;就怕但是。 #include int main() {long long v;v abs(-2147483648);printf("%lld\n", v);return 0; } 输出: -2147483648 我们从source code中一一解开. /* Return the absolute value of I. */ int abs (…