1 汇率转化
- 原生js的fetch请求
- 货币格式转化
// 货币转化表达式
money.toFixed(2).replace(/\d(?=(\d{3})+.)/g, “$&,”)
fetch(url)
.then(res => res.json()) //等价于return res.json()
.then(data => {})
/*
https://api.exchangerate-api.com/v4/latest/${val}
<option value="AED">阿联酋迪拉姆AED</option>
<option value="ARS">阿根廷比索ARS</option>
<option value="AUD">澳元AUD</option>
<option value="BGN">保加利亚列弗BGN</option>
<option value="BRL">巴西雷亚尔BRL</option>
<option value="BSD">白俄罗斯卢布BYR</option>
<option value="CNY" selected>人民币CNY</option>
<option value="DKK">丹麦克朗DKK</option>
<option value="EGP">埃及镑EGP</option>
<option value="EUR">欧元EUR</option>
<option value="FJD">斐济美元FJD</option>
<option value="GBP">英镑GBP</option>
<option value="GTQ">危地马拉格查儿GTQ</option>
<option value="HKD">港元HKD</option>
<option value="HRK">克罗地亚库纳HRK</option>
<option value="HUF">匈牙利福林HUF</option>
<option value="IDR">印尼盾IDR</option>
<option value="ILS">以色列新锡克尔ILS</option>
<option value="INR">印度卢比INR</option>
<option value="ISK">冰岛克朗ISK</option>
<option value="JPY">日元JPY</option>
<option value="KRW">韩元KRW</option>
<option value="KZT">哈萨克斯坦坚强戈KZT</option>
<option value="MXN">墨西哥比索MXN</option>
<option value="MYR">马来西亚林吉特MYR</option>
<option value="NOK">挪威克朗NOK</option>
<option value="NZD">新西兰元NZD</option>
<option value="PAB">巴拿马巴波亚PAB</option>
<option value="PEN">秘鲁索尔PEN</option>
<option value="PHP">菲律宾比索PHP</option>
<option value="PKR">巴基斯坦卢比PKR</option>
<option value="PLN">波兰兹罗提PLN</option>
<option value="PYG">巴拉圭瓜拉尼PYG</option>
<option value="RON">罗马尼亚新列伊RON</option>
<option value="RUB">卢布RUB</option>
<option value="SAR">沙特阿拉伯人里亚尔SAR</option>
<option value="SEK">瑞典克朗SEK</option>
<option value="SGD">新加坡元SGD</option>
<option value="THB">泰铢THB</option>
<option value="TRY">新土耳其里拉TRY</option>
<option value="TWD">新台币TWD</option>
<option value="UAH">乌克兰格里夫纳UAH</option>
<option value="USD">美元USD</option>
<option value="UYU">乌拉圭比索UYU</option>
<option value="VND">越南盾VND</option>
<option value="ZAR">南非兰特ZAR</option>
*/
2 数组方法
- in - 数组遍历
- forEach - 数组遍历
- map - 数组变量并返回新格式数组
- find - 查找符合条件的元素
- filter - 筛选符合条件的元素
- reduce - 元素求和
- sort - 数组排序
- includes - 判断是否包含某个元素
- splice - 删除/替换部分元素
- slice - 截取部分元素
- shift / pop - 删除首/尾元素
- unshift / push - 追加首/尾元素
- in
// 遍历arr的每个对象,nunber类型会被转化成string类型!!!
for(i in arr)
- forEach
// item:每个子元素 index:下标,无返回
arr.forEach((item,index) => {{})
- map
/*
item:每个子元素
index:下标
自定义返回内容组成新数组
*/
arr.map((item,index) => {{return ***})
- find
/*
item:每个子元素
index:下标
return true时返回当前item并结束遍历
仅返回一个元素
*/
arr.find((item,index) => {{return ***})
- filter
/*
item:每个子元素
index:下标
return true时返回该元素
返回多个元素组成新数组
*/
arr.filter((item,index) => {{return ***})
- reduce
/*
sum : 和
item:每个子元素
index:下标
init : sum的初始值
返回最终sum的值
*/
arr.reduce((sum,item) => {
return sum + num
},init)
[1,2,3].reduce((sum,item) => {
console.log(sum) // 0 1 3
return sum + item
},0)
- sort
/*
当return > 0 的值时交换a,b的顺序
类似冒泡排序法
*/
arr.sort((a,b) => {
return b - a//按降序
})
- includes
/*
判断数组是否包含某个元素,不能是对象或数组
与indexOf类似,单纯的判断时用includes更简洁
需要求下标时用indexOf
*/
const arr = [1,2,'3',{name : 'tom'}]
console.log(arr.includes(1)) //true
console.log(arr.includes(3)) //false
console.log(arr.includes('3')) //true
console.log(arr.includes({name : 'tom'})) //false
- splice
arr.splice(start,n,replace)
/*
删除/替换数组部分元素
从下标start开始删除n个元素
如果replace不为空则是用replace替代这n个元素
end可缺省,默认是最后一个元素
!! 不需要重赋值,会对原来的数组进行修改 !!
*/
- slice
arr = arr.slice(start,end)
/*
截取数组
从下标start开始到下标为end-1的数组
总共截取end - start个
end可缺省,默认是最后一个元素
可以用负数(0代表最后一位元素,-1代表倒数第二位元素)
返回截取的数组
需要重赋值
*/
- shift / pop
arr.shift() //去掉第一个元素,返回第一个元素
arr.pop() //去掉最后一个元素,返回最后一个元素
- push / unshift
arr.push(item) // 在末尾追加item,返回追加后的数组长度
arr.unshift(item) //在开头追加item,返回追加后的数组长度
3 折叠侧边栏
// 判断点击dom外
window.onclick = (e) => {
if(e.target === dom)
}
4 猜字游戏(svg)
优点 | 缺点 | |
---|---|---|
svg | 不依赖像素,放大后不失真,可直接绑定 dom | 动画性能低 |
canvas | 定制型强,动画效果好 | 依赖像素,绘制较复杂 |
<svg height="250" width="200" class="figure-container">
<!-- 起点坐标,终点坐标 -->
<line x1="60" y1="20" x2="140" y2="20" />
<!-- 圆心坐标,半径 -->
<circle cx="140" cy="70" r="20" />
</svg>
/* svg */
/* 填充 */
fill: transparent;
/* 边框 */
stroke: #fff;
/* 线宽度 */
stroke-width: 4px;
/* 边缘效果 */
stroke-linecap: round;
// 键盘事件
e.key // 获取输入的键名
e.keyCode // 键值(数字)
5 遗传算法求解二元函数极大值
种群(二维数组) -> 个体(一位数组) -> 基因(包含3个元素:x,y,z)
参数
rangeX - x的取值范围
rangeY - y的取值范围
coordinatesLength - 种群大小(二维数组长度)
evolveTimes - 进化次数(迭代次数)
copyRatio - 复制比例
crossNum - 交叉数量
总体步骤:
- 初始化参数
- 获取初代(根据x,y范围随机获取一组二维数组)
- 进化:
3.1 计算适应度(自然选择概率)
3.2 复制
3.3 交叉
3.4 变异
3.5 组合新种群继续进化 - 结束进化输出结果
个人对遗传算法的理解就是从一部分数据中选出好的数据,去掉坏的数据,然后对好的数据进行一些处理后继续选出好的数据。本质上还是个广撒点然后排序的问题,但是区别在于进化次数越多,后面的数据越集中在某个值。可能是我还没get到它的本质,所以一时间看不出啥优点。
1,2步就不多说了,直接写个随机函数就好了。
适应度(选择概率)
// 元素的第二位是函数的值
// 通俗点就是计算每个函数值占的一个权重
selectionProbability = []
const sum = calSum()
for (let i = 0; i < coordinatesLength; i++)
selectionProbability.push(coordArr[i][2] / sum)
function calSum() {
let sum = coordArr.reduce((val, item) => {
return item[2] + val
}, 0)
return sum
}
复制
// 从小到大排序后按复制比选择
function copy() {
let arr = [...coordArr]
arr = sortArr(arr)
arr = arr.slice(0, copyRatio * coordinatesLength)
return arr
}
function sortArr(Arr) {
let arr = [...Arr]
arr.sort((a, b) => {
return b[2] - a[2]
})
return arr
}
交叉
根据选择概率选中两个数据,对其中的x,y进行重新组合,有4种情况:
[x1,y1] [x1,y2] [x2,y1] [x2,y2]
let newCoord = []
for (let i = 0; i < crossNum; i++) {
let father = [...coordArr[RWS()]]
let mather = [...coordArr[RWS()]]
// 进行交叉
let results = [
[father[0],father[1]],
[father[0],mather[1]],
[mather[0],father[1]],
[mather[0],mather[1]]
]
let index = intRandom(0, 3)
newCoord.push(results[index])
}
/*
轮盘赌算法
概率大的容易被选中
*/
function RWS() {
let sum = 0
let rand = Math.random()
for (let i = 0; i < coordinatesLength; i++) {
sum += selectionProbability[i]
if (sum > rand)
return i
}
}
变异
function mutation(coord) {
// 在交叉的个体中随机选中一个
let coordIndex = intRandom(0, crossNum - 1)
// 随机获取x/y
let vector = intRandom(0, 1)
// 随机获取坐标值
let val = vector === 0 ? random(rangeX) : random(rangeY)
coord[coordIndex][vector] = val
return coord
}
组合新种群
直接把复制生成的数组跟变异后的数组组合起来即可,再重新求值,之后继续循环直至结束。
结果展示
图形绘制方面用到了echats库的散点图,传入的数据也是一个二维数组。echarts的散点图是根据每个元素的0,1元素绘制即:[横坐标,纵坐标]
// calculate
for (let i = 1; i <= evolveTimes; i++) {
// 计算适应度
calAdaptability()
// 复制
const copyArr = copy()
// 交叉
let newCoord = cross()
// 变异
newCoord = mutation(newCoord)
// 组合成新数组
coordArr = newCoord.concat(copyArr)
coordArr.forEach(item => {
item = getval(item)
})
data = data.concat(calData(i))
}
function calData(i) {
let arr = []
coordArr.forEach(item => {
arr.push([i, item[2]])
})
return arr
}
注:该算法未验证合理性,仅能确定输出的最大值正确。