资讯专栏INFORMATION COLUMN

javascript数组的常用算法解析

xumenger / 3190人阅读

摘要:对数组中的每一个元素都执行一次指定的回调函数,直到回调函数返回,此时返回并不再执行。二改变原数组针对每一个元素执行提供的函数。例如给定返回注意出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。

一、不改变原数组,返回新数组(字符串)

1、concat() 连接两个或者多个数组,两边的原始数组都不会变化,返回的是被连接数组的一个副本。

2、join() 把数组中所有的元素放入到一个字符串中,返回字符串

var a = [1,2,3];
a.join([4,5,6]);    //  "14,5,624,5,63"
a.join("sau");      //  "1sau2sau3"

3、slice() 从开始到结束(不包括结束)选择数组的一部分浅拷贝到一个新数组

var a  = [1,2,3,4,5];
a.slice(0,0);     //[]
a.slice(0,1);     //[1]
a.slice(2,4);    //[3,4]
a.slice(0,5);    //[1,2,3,4,5]
a.slice(10,1);   //[]
a.slice(4);   //[5]

4、map() 创建一个新的数组并返回,其中新数组的每一个元素由调用原始数组中的每一个元素执行提供的函数得来,原数组不变

5、every() 对数组中的每一个元素都执行一次指定的回调函数,直到回调函数返回false,此时every()返回false并不再继续执行,如果回调函数都对每一个元素都返回true,那么every()返回true。

6、some() 对数组中的每一个元素都执行一次指定的回调函数,直到回调函数返回true,此时some()返回true并不再执行。如果回调函数对每一个元素都返回false,那么some()将返回false。

7、filter() 创建一个新数组,其中包含通过所提供函数实现的测试的所有元素。

二、改变原数组

1、forEach() 针对每一个元素执行提供的函数。会修改原来的数组,不会返回执行结果,返回undefined。

2、pop() 删除数组最后一个元素,返回被删除的元素的值,如果数组为空,则不改变数组,返回undefined。

3、push() 向数组末尾添加一个或多个元素,返回改变后数组的长度。

4、reverse() 颠倒数组中元素的位置,返回该数组的引用。

5、shift() 从数组中删除第一个元素,改变原数组,并返回该元素的值。

6、unshift() 将一个或者多个元素添加到数组的开头,并返回新数组的长度。

7、sort() 对数组的元素进行排序,返回数组。排序不一定是稳定的。默认排序顺序是根据字符串unicode码点。

8、splice() 向数组中添加/删除元素,然后返回被删除的新数组()。

var a  = [1,2,3,4,5];
a.splice(0,1);     //删除从0位置开始的1个   返回[1]   a为[2,3,4,5] 
a.splice(1,0,99)   //在1的位置插入99   [2,99,3,4,5]
a.splice(1,1,88)   //99替换为88  [2,88,3,4,5]
三、遍历方法

1、获取属性名:for...in 和object.key()的区别

答:1、for in 遍历对象可以枚举的属性名列表,包括[[prototype]]原型链;

2、Object.keys() 只查找属性名是否在对象中,返回一个数组,包含所有可以枚举的属性名;

3、Object.getOwnPropertyNames()只查找属性名是否在对象中,返回一个数组,包含所有的属性名,不论是否可枚举。

2、获取属性值: for... of 和object.values()

for of 语句:遍历可迭代对象的可枚举属性值列表,包括[[propertype]]原型链;

object.values() :返回一个给定对象自身的所有可枚举属性的值,不包括原型链。

四、ES6语法Map键值对转化为数组

new Map创建一个map

// new Map创建一个map
let map = new Map([[1,"one"], [2,"two"], [3,"three"]]);
map.set(4, "four");
// 获取所有键值对
console.log("获取key")
console.log([...map.keys()]) // 输出[1, 2, 3, 4]

console.log("获取value")
console.log([...map.values()]) // 输出[one, two, three, four]

console.log("获取map数组")
console.log([...map]) // 输出[[1, "one"], [2, "two"], [3, "three"], [4, "four"]]
五、两个升序的数组合并成一个升序数组

1、时间复杂度O(M+N),空间复杂度O(M+N)

function merge(left, right){
    let result  = [],
        il      = 0,
        ir      = 0;

    while (il < left.length && ir < right.length) {
        result.push(left[il] < right[ir] ? left[il++] : right[ir++]);
console.log(result);
    }

    return result.concat(left.slice(il)).concat(right.slice(ir));
}

2、时间复杂度O(M+N),空间复杂度O(1)

   // m, n 是数组长度
function merge(left, m, right,  n) {
    var i = m - 1, j = n - 1, writeIdx = m + n - 1;
    while (i >= 0 && j >= 0)
    left[writeIdx--] = left[i] > right[j]? left[i--] : right[j--];
    while (j >= 0)
    left[writeIdx--] = right[j--];
    return left;
}
六、数组重复问题 (一)数组去重

1、reduce方法

const distinct = arr => arr.sort().reduce( (init, current) => {
    
    if (init.length === 0 || init[init.length - 1] !== current) {
        init.push( current );
    }
    return init;
}, []);

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
distinct(arr); // [1, 2, 3, 4, 5]

2、filter方法

const distinct = arr => arr.filter( (element, index, self) => {

return self.indexOf( element ) === index;

});

let arr = [1,2,1,2,3,5,4,5,3,4,4,4,4];
distinct(arr); // [1, 2, 3, 5, 4]

(二)排序数组去重
/**
 * @param {number[]} nums
 * @return {number}
 */
var removeDuplicates = function(nums) {
    
    if(!nums || nums.length == 0) return 0;
    
    let len = 0;
    for(let i = 1; i < nums.length; i++) {
        if (nums[len] != nums[i]) {
            nums[++ len] = nums[i];
        }
    }
    return len + 1;
};
(三)判断数组是否存在重复
/**
 * @param {number[]} nums
 * @return {boolean}
 */
var containsDuplicate = function(nums) {
    
    let hashMap = new Map();
    for(let i = 0; i < nums.length; i++) {
        
        if( hashMap.has(nums[i]) ) {
           return true;
        }
        
        hashMap.set(nums[i], 1);
    }
    
    return false;
};
七、两个数组的交集

给定两个数组,写一个方法来计算它们的交集。

例如:

给定 nums1 = [1, 2, 2, 1], nums2 = [2, 2], 返回 [2, 2].

注意:1、出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。2、

我们可以不考虑输出结果的顺序。
跟进:1、如果给定的数组已经排好序呢?你将如何优化你的算法?2、如果 nums1 的大小比 nums2 小很多,哪种方法更优?3、如果nums2的元素存储在磁盘上,内存是有限的,你不能一次加载所有的元素到内存中,你该怎么办?

解法:

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @return {number[]}
 */
var intersect = function(nums1, nums2) {
    
    var map1 = new Map();
    var number = [];
    
    for(var i = 0; i < nums1.length; i++) {
        var map1Value = map1.get(nums1[i]);
        map1.set( nums1[i], ( map1Value ? map1Value : 0 ) + 1 );
    }
    
    for(var i = 0; i < nums2.length; i++) {
        if( map1.has(nums2[i]) && map1.get(nums2[i]) != 0 ) {
            number.push(nums2[i]);
            map1.set( nums2[i], map1.get(nums2[i]) - 1 );
        }
    }
    
    return number;
};
八、找出一个数组中只出现一次的数字

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

/**
 * @param {number[]} nums
 * @return {number}
 */
var singleNumber = function(nums) {
    
    let number = 0;
    for(let i = 0; i < nums.length; i++) {
        number ^= nums[i];
    }
    return number;
};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102675.html

相关文章

  • CSS技巧

    摘要:技巧使你的更加专业这是上关于技巧的一篇译文,另外你也可以在本项目看到原文。列举了一些很实用的技巧,比如给空内容的标签添加内容,逗号分隔列表等等。排序算法看源码,把它背下来吧排序算法的封装。主要帮助初学者更好的掌握排序算法的实现。 成为专业程序员路上用到的各种优秀资料、神器及框架 成为一名专业程序员的道路上,需要坚持练习、学习与积累,技术方面既要有一定的广度,更要有自己的深度。 Java...

    DangoSky 评论0 收藏0
  • CSS技巧

    摘要:技巧使你的更加专业这是上关于技巧的一篇译文,另外你也可以在本项目看到原文。列举了一些很实用的技巧,比如给空内容的标签添加内容,逗号分隔列表等等。排序算法看源码,把它背下来吧排序算法的封装。主要帮助初学者更好的掌握排序算法的实现。 成为专业程序员路上用到的各种优秀资料、神器及框架 成为一名专业程序员的道路上,需要坚持练习、学习与积累,技术方面既要有一定的广度,更要有自己的深度。 Java...

    zgbgx 评论0 收藏0
  • JavasScript重难点知识

    摘要:忍者级别的函数操作对于什么是匿名函数,这里就不做过多介绍了。我们需要知道的是,对于而言,匿名函数是一个很重要且具有逻辑性的特性。通常,匿名函数的使用情况是创建一个供以后使用的函数。 JS 中的递归 递归, 递归基础, 斐波那契数列, 使用递归方式深拷贝, 自定义事件添加 这一次,彻底弄懂 JavaScript 执行机制 本文的目的就是要保证你彻底弄懂javascript的执行机制,如果...

    forsigner 评论0 收藏0
  • 一名【合格】前端工程师自检清单

    摘要:在他的重学前端课程中提到到现在为止,前端工程师已经成为研发体系中的重要岗位之一。大部分前端工程师的知识,其实都是来自于实践和工作中零散的学习。一基础前端工程师吃饭的家伙,深度广度一样都不能差。 开篇 前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,技术迭代速度之快是其他技术所不能比拟的。 winter在他的《重学前端》课程中提到: 到现在为止,前端工程师已经成为研...

    罗志环 评论0 收藏0
  • 一名【合格】前端工程师自检清单

    摘要:在他的重学前端课程中提到到现在为止,前端工程师已经成为研发体系中的重要岗位之一。大部分前端工程师的知识,其实都是来自于实践和工作中零散的学习。一基础前端工程师吃饭的家伙,深度广度一样都不能差。开篇 前端开发是一个非常特殊的行业,它的历史实际上不是很长,但是知识之繁杂,技术迭代速度之快是其他技术所不能比拟的。 winter在他的《重学前端》课程中提到: 到现在为止,前端工程师已经成为研发体系...

    isaced 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<