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.priceListvar 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.priceListvar 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;
},

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

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

相关文章

Linux —— 线程同步

Linux —— 线程同步 死锁线程同步条件变量pthread_cond_waitpthread_cond_signal初始状态为什么之后会“阻塞”如何修改以持续运行 pthread_cond_broadcast 条件变量的接口抢票模拟 我们今天接着来了解线程&#xff1a; 死锁 死锁&#xff08;Deadlock&#xff09;是计算机科…

基础编程函数题

1.简单输出整数&#xff1a;本题要求实现一个函数&#xff0c;对给定的正整数N&#xff0c;打印从1到N的全部正整数。 #include <stdio.h> void PrintN ( int N ); int main () { int N; scanf("%d", &N); PrintN( N ); return 0; } void Prin…

会所前台装水离子雾化壁炉前和装后对比

会所前台装水离子雾化壁炉前和装后会有明显的对比&#xff1a; 装水离子雾化壁炉之前&#xff1a; 普通前台氛围&#xff1a; 在壁炉安装之前&#xff0c;前台可能显得普通&#xff0c;缺乏独特的装饰元素或焦点。 空间感平淡&#xff1a;前台的氛围可能相对平淡&#xff0c…

Python踩坑系列之使用redis报错:module ‘redis‘ has no attribute ‘Redis‘问题

一步一步往后看哦&#xff01;&#xff01;&#xff01; 纳尼&#xff0c;大伙看看这是什么情况&#xff0c;都是这么写的呢&#xff0c;为啥我这就报错了0.0 出现问题不可怕&#xff0c;解决它就完事了。 方法一、安装redis重新运行程序 pip install redis 无果&#xff0…

金丝雀发布(灰度发布)介绍 及 声明式管理方法简介

目录 一 应用发布策略 1&#xff0c;滚动发布&#xff08;k8s默认&#xff09; 2&#xff0c;蓝绿发布 3&#xff0c;金丝雀发布 二 金丝雀发布&#xff08;Canary Release&#xff09; &#xff08;灰度发布&#xff09; 1&#xff0c;金丝雀发布图解 2&#xff0…

数据库操作(函数)

函数是一段可以直接被另外一段程序调用的程序或代码 一。字符串函数 1.concat(s1,s1....sn)&#xff1a;字符串拼接&#xff0c;将s1&#xff0c;s2&#xff0c;sn拼接为一个字符串 例如&#xff1a; select concat("hello","world"); 2.lower(str&…

登录验证登录次数失败过多进行设置延时

现象结果示例截图 swagger示例效果 控制台示例效果 后端代码示例 package com.java.javamethod.service.impl;import com.java.javamethod.dao.UserMapper; import com.java.javamethod.domain.Result; import com.java.javamethod.domain.User; import lombok.extern.slf4j.…

《绝地潜兵2》开发商目标成为下一个暴雪或FS社

《绝地潜兵2》的开发商Arrowhead正以惊人的表现在游戏界崭露头角。这款游戏在发售后迅速获得了巨大成功&#xff0c;使得Arrowhead的首席创意官Johan Pilestedt怀揣雄心壮志&#xff0c;他们的目标是在保持独立的同时&#xff0c;成为下一个暴雪或From Software。 Johan Pilest…

firewalld

一、Firewalld概述 Firewalld 支持网络区域所定义的网络链接以及接口安全等级的动态防火墙管理工具 支持IPV4、IPV6防火墙设置以及以太网桥 支持服务或应用程序直接添加防火墙规则接口 拥有两种配置模式 运行时配置 永久配置 二、Firewalld和iptables的关系 netfilter 位于L…

10个最佳Android数据恢复工具,用于恢复已删除的文件

由于我们现在在智能手机上存储了许多重要文件&#xff0c;因此了解数据恢复工具变得很重要。您永远不会知道何时需要使用适用于Android的数据恢复工具。 由于不乏Windows数据恢复工具&#xff0c;因此从崩溃的计算机中恢复文件很容易。但是&#xff0c;当涉及到从Android恢复数…

兆原数通基于Apache SeaTunnel的探索实践

随着大数据技术的不断发展&#xff0c;数据同步工具在企业中的应用变得愈发重要。为了满足复杂多样的业务需求&#xff0c;找到一款高效、灵活的数据同步工具变得尤为关键。 在这篇文章中&#xff0c;我们将分享兆原数通研发经理李洪军对Apache SeaTunnel的选择、应用及经验。这…

jinkens打包前端依赖下载失败怎么办

不知道有没有小伙伴遇见这种问题&#xff0c;项目在本地可以正常下载、运行打包&#xff0c;但在jinkens上就不行了&#xff0c;配置了几种镜像也还是不行&#xff0c;这要如何解决呢&#xff1f; 那就只能去到jinkens配置的工作空间那里&#xff0c;找到对应的项目 &#xff…

总结优秀的prompt案例,学习更有效的prompt提示词工程写法,值得收藏

Prompt 提示词工程大多数人都在用&#xff0c;而且都会用&#xff0c;但是不一定写的好&#xff1f;很多人都在想怎么写好&#xff0c;更能满足自己的业务需求&#xff0c;或者实际场景。 我最近工作中也写了很多的prompt&#xff0c;像zero-shot、few-shot、COT这些都尝试过、…

FSC认证是什么?森林认证的好处是什么?

FSC认证&#xff08;Forest Stewardship Council&#xff0c;森林管理委员会认证&#xff09;是一种运用市场机制来促进森林可持续经营&#xff0c;实现生态、社会和经济目标的工具。以下是关于FSC认证的详细介绍&#xff1a; 一、FSC认证包括两个方面&#xff1a; 森林经营认…

乡村振兴与农业现代化:以现代农业科技为引领,提升农业综合生产能力,打造高产高效、生态安全的美丽乡村

目录 一、引言 二、现代农业科技在乡村振兴中的作用 &#xff08;一&#xff09;提高农业生产效率 &#xff08;二&#xff09;促进农业产业升级 &#xff08;三&#xff09;改善农村生态环境 三、提升农业综合生产能力的途径 &#xff08;一&#xff09;加强农业科技研…

Diffusion Policy:基于扩散模型的机器人动作生成策略

项目地址&#xff1a; Diffusion Policy (columbia.edu) 一、摘要 本文介绍了 "扩散策略"&#xff0c;这是一种生成机器人行为的新方法&#xff0c;它将机器人的视觉运动策略&#xff08;visuomotor policy&#xff09;表示为条件去噪扩散过程&#xff08;conditi…

添加、修改和删除列表元素

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 添加、修改和删除列表元素也称为更新列表。在实际开发时&#xff0c;经常需要对列表进行更新。下面我们介绍如何实现列表元素的添加、修改和删除。 …

如何使用Matlab进行三角剖分(自定义函数实现delaunayTriangulation 使用Bowyer-Watson 算法)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 前言 一、Delaunay三角形 二、使用步骤 1.Bowyer-Watson算法 2.算法步骤 三、动画演示 四、核心代码 五、对比matlab自带函数和我们的算法&#xff1a; 总结 前…

谷歌开源项目BERT源码解读与应用实例

数据及代码见文末 基于BERT的中文情感分析实战:基于BERT的中文情感分析实战-CSDN博客 基于BERT的中文命名实体识别识别实战:基于BERT的中文命名实体识别识别实战-CSDN博客 1.项目配置文件 GLUE/BERT_BASE_DIR是项目的预训练权重,预训练权重主要包含3个部分:参数配置文件…

打气球小游戏

1.气球往上飘 我们声明两个符号常量来作为窗体的长和宽,接着就是常规操作 #define WINDOW_WIDTH 800 #define WINDOW_HEIGHT 600#include<easyx.h> #include<stdio.h> int main() {initgraph(WINDOW_WIDTH, WINDOW_HEIGHT);setbkcolor(WHITE);cleardevice();get…