Json Stringify
Version sort
正常通过字符串比较是不足以应对大部分场景的,因为字符串是通过 unicode 的顺序去排序的。所以会出现如下情况:
> a='5'
'5'
> b='201'
'201'
> a < b
false
所以单纯的字符串比较是不合理的,所以当我们需要比较版本号,普适的方式是循环比较法:
arr.sort((a, b) => {
let i = 0;
const arr1 = a.split('.');
const arr2 = b.split('.');
while (true) {
const s1 = arr1[i];
const s2 = arr2[i++];
if (s1 === undefined || s2 === undefined) {
return arr2.length - arr1.length;
}
if (s1 === s2) continue;
return s2 - s1;
}
});
此外还有一种加权的方式,这种方式适合版本号格式比较固定的情况。当版本的格式不够统一时需要多操作一步。具体代码如下:
const maxLen = Math.max(
...arr.map((item)=>item.split('.').length)
);
const reducer = (acc,value,index) =>
acc+(+value)*Math.pow(p,maxLen-index-1);
const gen = (arr) =>
arr.split('.').reduce(reducer,0);
arr.sort((a,b)=> gen(a)>gen(b)?-1:1);
console.log(arr)
Array Deep Copy
深拷贝一般是在数组里面的内容是对象的时候使用,可以通过如下的例子来看下区别:
> a = [1,2,3]
[ 1, 2, 3 ]
> b = [...a]
[ 1, 2, 3 ]
> a[1]=5
5
> b
[ 1, 2, 3 ]
可以看到当数组内容是简单类型时,修改源数组的内容,不会对拷贝后的数组产生影响。下面是一个对象拷贝的例子:
> a = [ {k1:1, k2:2}, {k1:2, k2:3} ]
[ { k1: 1, k2: 2 }, { k1: 2, k2: 3 } ]
> b = [...a]
[ { k1: 1, k2: 2 }, { k1: 2, k2: 3 } ]
> a[0].k1=5
5
> b
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
可以看到,当修改了 a 中内容后,b 中的内容发生了变化。此时我们需要使用深拷贝来解决这个问题。
> c = a.map(item => { return { ...item} })
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
> a
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
> a[0].k1=6
6
> c
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
>
可以看到此时的 c 并没有因为 a 中的内容发生变化而发生变化。 还有另外一种深拷贝方式,相比较于 map 的方式略慢一些。
> d = JSON.parse(JSON.stringify(a))
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
> a
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]
> a[0].k1=6
6
> d
[ { k1: 5, k2: 2 }, { k1: 2, k2: 3 } ]