基本操作

一维数组与二维数组互相转换

求余实现

  1. //求余(%) 12%5返回2
  2. let baseArray = [1, 2, 3, 4, 5, 6, 7, 8]
  3. let len = baseArray.length
  4. // 假设每行显示四个
  5. let n = 4
  6. // 求余
  7. let lineNum = len % n === 0 ? len / n : Math.floor((len / n) + 1)
  8. // let lineNum = Math.ceil(len/4)
  9. let res =[]
  10. for(let i=0;i<lineNum;i++){
  11. // (0,4) (4,8)
  12. let temp = baseArray.slice(i*n,i*n+n)
  13. res.push(temp)
  14. }
  15. console.log(res) //[[1, 2, 3, 4],[5, 6, 7, 8]]
  1. let baseArray = [1, 2, 3, 4, 5, 6, 7, 8]
  2. // 假设每行显示四个
  3. let n = 4
  4. let res = []
  5. baseArray.forEach((item,index)=>{
  6. if(!res[Math.floor(index/n)]){
  7. res[Math.floor(index/n)] =[]
  8. }
  9. res[Math.floor(index/n)].push(item)
  10. })
  11. console.log(res)
  12. // (2) [Array(4), Array(4)]
  13. // 0: (4) [1, 2, 3, 4]
  14. // 1: (4) [5, 6, 7, 8]

递归法

  1. function change2Array(data, len, arr) {
  2. /**
  3. * @param data 一维数组
  4. * @param len 每个子数组长度
  5. * @param arr 保存的新数组
  6. */
  7. if (data.length <= len) {
  8. arr.push(data);
  9. console.log(arr)
  10. return arr;
  11. } else {
  12. arr.push(data.splice(0, len));
  13. change2Array(data, len, arr);
  14. }
  15. }
  16. 注意 splice push 都是会改变原数组的

二维数组转换为一维数组

  1. const arr=[[1,2,3],[3,4],[5]];
  2. var newarr = [].concat.apply([],arr)
  3. console.log(newarr)
  4. call 是不可以的
  5. call apply 的区别 传参的不同
  1. let flattened = [[0,1],[1,2]].reduce(function(a,b){
  2. return a.concat(b)
  3. })
  4. console.log(flattened) //[0, 1, 1, 2]

参考文档 https://segmentfault.com/a/1190000016038640

数组与字符串的相互转换 (Array String )

1) array 转换成 string
arr.toString()

  1. let arr = ["111","222"]
  2. console.log(arr.toString()) //111,222
  3. let arr = ["111","222",[22]]
  4. console.log(arr.toString()) //111,222,22
  5. let arr = ["111","222",{"a":111}]
  6. console.log(arr.toString()) //111,222,[object Object]

arr.join()

  1. let arr = ["111","222",[22]]
  2. console.log(arr.join(",")) //111,222,22

2)string 转换成 array
arr.split()

  1. let arr = "111,222"
  2. console.log(arr.split(",")) //["111", "222"]

数组降维

1.双重遍历二维数组中的每个元素并放到新数组中

  1. function reduceDimension(arr){
  2. var reduced = [];
  3. for(var i=0;i<arr.length;i++){
  4. for(var j=0;j<arr[i].length;j++){
  5. reduced.push(arr[i][j])
  6. }
  7. }
  8. return reduced
  9. }

2.利用concat 转换
concat()不改变原数组 用于合并两个或多个数组 返回一个新数组

  1. function reduceDimension(arr){
  2. var reduced = [];
  3. for(var i=0;i<arr.length;i++){
  4. reduced = reduced.concat(arr[i])
  5. }
  6. return reduced;
  7. }

3.利用apply 和 concat 转换

  1. function reduceDimension(arr) {
  2. return Array.prototype.concat.apply([], arr);
  3. }

首字母大写

  1. function ucFirst(arr){
  2. return arr.slice(0,1).toUpperCase() + arr.slice(1)
  3. }
  4. ucFirst("ahello")
  5. 不能“替换”第一个字符,因为在js中字符串是不可变得
  6. 但是我们可以根据已有字符串创建一个首字母大写的新字符串
  7. let newStr = str[0].toUpperCase() + str.slice(1)
  8. 存在问题 如果str是空的,那么str[0] 就是 undefined 但由于undefined 没有toUpperCase()方法
  9. 因此会得到一个错误
  10. 存在如下两种变体:
  11. 1.使用str.charAt(0) 因为它总是会返回一个字符串 (可能为空)
  12. 2.为空字符添加测试
  13. function ucFirst(str) {
  14. if (!str) return str;
  15. return str[0].toUpperCase() + str.slice(1);
  16. }
  17. alert( ucFirst("john") ); // John

对数组中的图片地址处理

场景 服务器返回的图片地址 有的加上域名有的直接是图片在服务器上面的地址 需要进行处理

  1. 需要注意的是 结果是会返回一个新的数组
  2. let urlbase = "http://www.baidu.com"
  3. let a = ['1','http://www.xxx.xxx.png','3','4']
  4. let newarr = a.map(function(value,index,arr){
  5. if(value.includes('http')){
  6. return value
  7. }else{
  8. return urlbase + value
  9. }
  10. })
  11. console.log(newarr)

将数组中的字符串转换为数字

  1. 将字符串转换为数字
  2. let arr = ["1","2","3","4"]
  3. var res = arr.map(x=>Number(x))
  4. console.log(res) // [1, 2, 3, 4]
  5. console.log(typeof(res[0])) // number

取出 对象数组 中的值

实际应用 分类列表中 左边菜单的文字 在整个数据中取出重新组成单独的菜单数据

  1. let data = [
  2. {
  3. title:"111",
  4. children:[]
  5. },
  6. {
  7. title:"111",
  8. children:[]
  9. }
  10. ]
  11. var newarr = data.map(x=>x.title)
  12. console.log(newarr) //["111", "111"]

求和问题

参数不固定
reduce arguments

reduce 只适用于 数组相加

  1. function sum(...args){
  2. return args.reduce((s,v)=>{
  3. return s+=v
  4. },0)
  5. }
  6. console.log(sum(1,2,3,4))

arguments

  1. function sum(){
  2. // console.log(arguments)
  3. let total = null;
  4. for(let i=0;i<arguments.length;i++){
  5. //获取的每一项的结果都需要转换为数字(数学运算)
  6. let item = Number(arguments[i])
  7. //非有效数字不加
  8. if(isNaN(item)){
  9. continue
  10. }
  11. total += item
  12. }
  13. return total;
  14. }
  15. let total = sum(10,20)
  16. console.log(total)
  17. total = sum(10,20,"30")
  18. console.log(total)

验证手机号

  1. var reg = /^1[0-9]{10}$/;

常见数组的应用

判断某个数是不是奇数

判断某个数是不是素数

数组求和

数组中的最大值

数组中的最小值

数组是否是稀松数组

什么是稀松数组:数组的元素不是连续有值。

  1. var arr=new Array(3);
  2. arr[0] = 1
  3. arr[2] = 3
  4. 其中arr[1]=undefined;

某年是否为闰年

  1. //4年一闰,百年不闰;400年一闰

得到某年某月的天数

得到某个数字数组中出现次数最多的数字和频率

取出数组对象中的某些值重新组成一个新的数组

  1. 将下例的数据重新组成一个新的值得数组
  2. let arr = [
  3. {
  4. name: "酒水",
  5. seq: 0,
  6. type: 102
  7. },
  8. {
  9. name: "西瓜",
  10. seq: 12,
  11. type: 102
  12. }
  13. ]
  14. let newArr = []
  15. arr.forEach(item=>{
  16. newArr.push({
  17. text:item.name,
  18. value:item.seq
  19. })
  20. })
  21. console.log(newArr)

生成指定范围的随机数

  1. function getRandom(n, m) {
  2. //生成[0,10]之间,在加上 70 即可
  3. var num = Math.floor(Math.random() * (m - n + 1) + n)
  4. return num
  5. }
  6. var number = getRandom(70,80)
  7. console.log(number)

创建一个 [1…100]的数组

  1. let arr = []
  2. // push方法
  3. for(let i = 1,len=100;i<=100;i++){arr.push(i)}
  4. //循环赋值
  5. for(let i = 1,len=100;i<=100;i++){arr[i-1]=i}
  6. // Array.from()方法 后面会有一点点的优化
  7. Array.from({length:101}, (v,k) => k)// or Array.from(Array(101), (v,k) =>k);
  8. Array.from(Array(101).keys())
  9. arr.splice(0,1)
  10. [...Array(100).keys()]// 0-> 99
  11. [...Array.from({length:100}).keys()]// 0-> 99
  12. Array.from(new Array(100).keys())
  13. // mdn 看见的 序列生成器(指定范围)
  14. const range = (start, stop, step) => Array.from({ length: (stop - start) / step + 1}, (_, i) => + (i * step));
  15. range(1,100,1)// 1-> 100
  16. Array.from({length:100},(_, i)=>1+(i)) // 1-> 100

实际应用-数组

投影数组
对某个值执行一个函数,以得到新的值,这种操作叫做投影。为了把一个数组投影成另一个数组,我们对数组中的每个元素都执行一个投影函数,然后把所有的结果收集起来,组成新的数组。

过滤数组

1.对数组中的值进行筛选过滤在重新组合

投影数组 场景: 把一个包含 video 信息的数组投影成包含{id,title}对的新数组

  1. var newArr = message.map(item=>{
  2. return {name:item.name}
  3. })
  4. //return item.name 返回的是一个数组

2.将数组中的值变成对象的键值 形式

for in 循环方式

  1. let obj = {}
  2. for(var item in message){
  3. obj[message[item].value] = message[item].name
  4. }
  5. console.log(obj)

map循环方式

  1. let obj = {}
  2. var newArr = message.map(e=>{
  3. obj[e.value] = e.name
  4. })
  5. console.log(obj)

3.根据数组中的某一项值进行排序

  1. var message = [{
  2. name: "个人待办",
  3. value: "personal_standby",
  4. order:1
  5. },
  6. {
  7. name: "流程跟踪",
  8. value: "process_tracking",
  9. order:2
  10. },
  11. {
  12. name: "应用推荐",
  13. value: "application_recommendation",
  14. order:4
  15. },
  16. {
  17. name: "最新应用",
  18. value: "latest_application",
  19. order:3
  20. },
  21. {
  22. name: "周期性应用",
  23. value: "period_application",
  24. order:5
  25. },
  26. {
  27. name: "专题推荐",
  28. value: "sbject_rommendation",
  29. order:7
  30. },
  31. {
  32. name: "收藏服务",
  33. value: "collect_service",
  34. order:6
  35. }
  36. ]
  37. //
  38. function compare(p){
  39. return function(a,b){
  40. var value1 = a[p]
  41. var value2 = b[p]
  42. return value1 - value2
  43. }
  44. }
  45. var res = message.sort(compare('order'))
  46. console.log(res)

4.往数组中添加属性

  • map方法

    1. var arr = message.map((item,index)=>{
    2. item.id = index
    3. return item //一定要在这儿return
    4. })
    5. console.log(arr)
  • Object.assign()

    补充 Object.assign(target, …sources)

    target 目标对象 sources 源对象

下面的写法等于是把 item 与 {mess:1} 进行组合

  1. var array2 = []
  2. message.map((item,index)=>{
  3. array2.push(Object.assign({},item,{mess1:1}))
  4. })
  5. console.log(array2)

5.对数组中重复的值进行去重

  1. var arr2 = [{
  2. name: "name1",
  3. num: "1"
  4. },
  5. {
  6. name: "name2",
  7. num: "11"
  8. },
  9. {
  10. name: "name3",
  11. num: "12"
  12. },
  13. {
  14. name: "name4",
  15. num: "13"
  16. },
  17. {
  18. name: "name2",
  19. num: "1"
  20. },
  21. {
  22. name: "name6",
  23. num: "12"
  24. }
  25. ]
  26. function arrayUnique2(arr,name){
  27. var hash = {}
  28. return arr.reduce(function(item,next){
  29. hash[next[name]] ? '': hash[next[name]] = true && item.push(next)
  30. return item
  31. },[])
  32. }
  33. console.log(arrayUnique2(arr2,"name"))
  34. //代码分析
  35. hash[next[name]] = true && item.push(next)
  36. 将这个值作为一个记号进行标记

备注:上面的这个去重方法是取第一个出现的值,后面再有值的话是不会进行覆盖的。

如果要取最新的一个值该如何?


另一种方法

  1. function unique(arr) {
  2. const res = new Map();
  3. return arr.filter((a) => !res.has(a.name) && res.set(a.name, 1))
  4. }
  5. console.log(unique(arr2))

数组去重
利用 es6 set去重
备注:set 的这种形式去重只能是 单个数组的形式,对象数组不适用。

  1. var arr =[1,2,3,4,5,6,3,2,3]
  2. function unique(arr){
  3. return Array.from(new Set(arr))
  4. }
  5. console.log(unique(arr))
  6. //也可以另一种形式的写法
  7. var arr2 = [{
  8. name: "name1",
  9. num: "1"
  10. },
  11. {
  12. name: "name2",
  13. num: "11"
  14. },
  15. {
  16. name: "name3",
  17. num: "12"
  18. },
  19. {
  20. name: "name4",
  21. num: "13"
  22. },
  23. {
  24. name: "name6",
  25. num: "12"
  26. }]
  27. let res = [...new Set(arr2.map(item=>item.num))]

reduce 用法

文章链接

6.判断对象数组中是否存在某个对象

数组方法 some 判断

  1. var arr = [{
  2. name: "常用"
  3. }, {
  4. name: "1"
  5. }]
  6. var obj = {
  7. name: "5"
  8. }
  9. var result = arr.some(item => {
  10. if (this.obj.name === item.name) {
  11. return true
  12. }
  13. })
  14. if (result) {
  15. console.log("已经存在")
  16. } else {
  17. this.arr.push(obj)
  18. }
  19. console.log(arr)

1.判断数组中是否存在耨个元素,indexOf()

  1. var arr = [1,2,3,4]
  2. console.log(arr.indexOf(3)) //2
  3. console.log(arr.indexOf(8)) //-1

2.只判断情况下,可以遍历后判断对象的属性是否相同

  1. arr.forEach(item=>{
  2. if(item.name=='Alex'){
  3. console.log('存在这个元素');
  4. }
  5. })

3.设一个flag来做判断的标识

  1. var arr = [{
  2. name: "常用"
  3. }, {
  4. name: "1"
  5. }]
  6. var obj = {
  7. name: "1"
  8. }
  9. let flag = true
  10. arr.forEach(item=>{
  11. if(obj.name == item.name){
  12. flag = false
  13. }else{
  14. flag = true
  15. }
  16. })
  17. if(flag){
  18. arr.push(obj)
  19. }else{
  20. console.log("已存在")
  21. }
  22. console.log(arr)

7.reduce 的高级使用

  1. var result = [
  2. {
  3. subject: 'math',
  4. score: 88
  5. },
  6. {
  7. subject: 'chinese',
  8. score: 95
  9. },
  10. {
  11. subject: 'english',
  12. score: 80
  13. }
  14. ];
  15. //for 循环
  16. var sum = 0;
  17. for(var i=0; i<result.length; i++) {
  18. sum += result[i].score;
  19. }
  20. //reduce
  21. var sum = result.reduce(function(prev, cur) {
  22. return cur.score + prev;
  23. }, 0);
  24. //错误写法
  25. var sum = result.reduce(function(prev, cur) {
  26. return cur.score + prev.score ;
  27. }, 0);

这个时候,我给reduce参数添加了第二个参数。通过打印我发现设置了这个参数之后,reduce遍历便已经从第一项开始了。 这第二个参数就是设置prev的初始类型和初始值,比如为0,就表示prev的初始值为number类型,值为0,因此,reduce的最终结果也会是number类型。

https://segmentfault.com/a/1190000005921341

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/flat#%E8%AF%AD%E6%B3%95

flat()

flat() 方法会按照一个可指定的深度递归遍历数组,并将所有元素与遍历到的子数组中的元素合并为一个新数组返回。
示例
扁平化嵌套数组

  1. var arr1 = [1, 2, [3, 4]];
  2. arr1.flat();
  3. // [1, 2, 3, 4]
  4. var arr2 = [1, 2, [3, 4, [5, 6]]];
  5. arr2.flat();
  6. // [1, 2, 3, 4, [5, 6]]
  7. var arr3 = [1, 2, [3, 4, [5, 6]]];
  8. arr3.flat(2);
  9. // [1, 2, 3, 4, 5, 6]
  10. //使用 Infinity,可展开任意深度的嵌套数组
  11. var arr4 = [1, 2, [3, 4, [5, 6, [7, 8, [9, 10]]]]];
  12. arr4.flat(Infinity);
  13. // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

扁平化与数组空项
flat() 方法会移除数组中的空项:

  1. var arr4 = [1, 2, , 4, 5];
  2. arr4.flat();
  3. // [1, 2, 4, 5]

替代方案
使用 reduce 与 concat

  1. var arr = [1, 2, [3, 4]];
  2. // 展开一层数组
  3. arr.flat();
  4. // 等效于
  5. arr.reduce((acc, val) => acc.concat(val), []);
  6. // [1, 2, 3, 4]
  7. // 使用扩展运算符 ...
  8. const flattened = arr => [].concat(...arr);

相关文章
https://github.com/mqyqingfeng/Blog/issues/36
https://juejin.cn/post/6844903805876699150#heading-5
https://www.cnblogs.com/lynn-z/p/13915539.html


数组原理

1.map

  1. Array.prototype.myMap = function (projectionFunction) {
  2. var results = [];
  3. this.forEach(function (item) {
  4. return results.push(projectionFunction(item));
  5. });
  6. return results;
  7. };
  8. //test
  9. var arr = [1, 2, 4, 5, 6, 7];
  10. let newArr = arr.myMap(function (x) {
  11. return x + 1;
  12. });
  13. console.log(newArr);

2.filter

为了让过滤操作更简单, 我们给数组类型添加一个 filter() 函数。 filter() 接受一个断言作为参数。 断言是这样一个函数: 它以数组中的一个元素作为参数,返回一个布尔值,表明这个元素应不应该被添加到新数组中。

  1. Array.prototype.filter = function (predicateFunction) {
  2. var results = [];
  3. this.forEach(function (itemInArray) {
  4. //看返回是不是 true
  5. return predicateFunction(itemInArray) && results.push(itemInArray);
  6. });
  7. return results;
  8. };