1、有一道颇有意思的数组操做相关编程题,闲来无事用JS解决了一下,问题描述以下:程序员
(1) 键盘录入6个int类型的数据存入数组arr中;编程
(2) 将arr数组中的内容反转;数组
(3) 将反转后的数组角标为奇数的元素相互交换,即1和3交换,3和5交换,以此类推;数据结构
(4) 将数组中最后一个角标为奇数的元素和数组中第一个角标为奇数的元素交换;函数
(5)打印最终的数组,(实现了1—4步以后的数组)spa
示例:如用户输入的6个整数为[1,2,3,4,5,6]>[6,5,4,3,2,1]>[6,3,4,1,2,5]>最后输出[6,5,4,1,2,3].prototype
2、问题分析:这是一道整数数组操做的题目,考察对数组基本操做方法的熟练度。若是用JS编程,(2)中反转很容易完成,用Array.prototype.reverse()方法便可;重点在第(3)、(4)步。须要循环数组处理奇数位交换问题。同时要记录下最后一个奇数位的元素索引值(数组下标为奇数的最后一个元素)。指针
同时,做为程序员分析问题必定要综合考虑全部状况,适当拓展,不能只停留在解决这个示例数组[1,2,3,4,5,6]的问题上,而要把它当作是任意长度的数组。在这里咱们就把它当成一个任意长度的数组arr。再依次进行题中的操做。code
3、问题解决,JavaScript代码以下:对象
const getArr = (arr) => { const arrRe = arr.reverse();//反转数组 console.log('数组反转:', arrRe); const exchange = (arr, m, n = m + 2) => {//参数n=m+2,含义是若是传入参数n(不能传入undefined)则取传入参数,若是没有传入或者传入undefined(如传入null,会取null不会取m+2)则取m+2. const vm = arr[m]; arr[m] = arr[n]; arr[n] = vm;//注意此时vm的值仍是数组交换前arr[m]的值,不会随数组交换而改变 }; let i = 1;//i定义在外层,做为循环变量的同时,记录最后一个奇数位下标 for (; i + 2 < arr.length; i += 2) { exchange(arrRe, i);//对数组arrRe循环依次进行奇数位交换操做 } console.log('奇数位交换:', arrRe); exchange(arrRe, 1, i);//交换首个奇数位元素和最后一个奇数位元素arrRe[i] console.log('首个奇数位和最后一个奇数位交换(最终结果):', arrRe); return arrRe; }; //运行以下代码: getArr([1,2,3,4,5,6]); /* 依次输出: 数组反转: [6, 5, 4, 3, 2, 1] 奇数位交换: [6, 3, 4, 1, 2, 5] 首个奇数位和最后奇数位交换(最终结果): [6, 5, 4, 1, 2, 3] */
(本文为原创博客,转载请注明出处:https://www.cnblogs.com/xiao-pengyou/)
注意:数组是引用类型,JS中的Object和Array都是引用类型,即常量arr是指向数组[1,2,3,4,5,6]内存地址的一个指针,全部在数组上的操做都会被自动记录即原数组记录一切改变,数组做为函数传入参数的时候也是传入了数组的引用,故在函数内的操做也会改变原数组或对象,以上代码全部改变arr的操做都做用于arr原数组,指针始终没变。所以进行操做时没必要关心如何记录原数组的变化,只须要进行一系列操做最终获得想要的结果便可。
4、数组知识拓展:
若是想要拷贝一个数组,能够使用Array.prototype.concat()或者Array.prototype.slice()实例方法(对象的方法分为实例方法和静态方法,不做详述,网上不少资料能够自行查阅)。示例代码以下:
const arr = [1,2,3]; const arr1 = arr; const arr2 = [].concat(arr); const arr3 = arr.slice();//至关于arr.slice(0) arr[0] = 4; arr1;//[4,2,3] arr2;//[1,2,3] arr3;//[1,2,3] //可见数组arr的改变不会影响arr2和arr3.
虽然Array.prototype.concat()或者Array.prototype.slice()拷贝的数组不会受原数组影响,可是它们也不是真正意义上的深拷贝,由于若是数组的某个元素仍是引用类型,如[[1,2], 2, 3]用concat()拷贝以后的数组的第一个元素[1,2]仍是会受原数组的影响,因此没有真正实现深拷贝,只是一种浅拷贝。深浅拷贝是相对于引用类型。
深拷贝:深度拷贝就是拷贝后的对象和原对象(JS中万物皆为对象,因此此处把引用类型都叫作对象)的内存和之后的操做都互不影响。拷贝的时候为新对象开辟了新的内存而不是拷贝原对象的引用。
浅拷贝:浅拷贝是拷贝原对象的引用,拷贝后的对象和原对象会相互影响。由于引用不变,指针指向的内存地址不变, 任一对象的改变都会引发全部该内存位置对应对象的改变。
注:
基本类型,存放在栈(stack,相似数据结构中的栈)中(编译器自动分配释放),
引用类型,值大小不固定,在栈内存中存一个基本类型值保存对象在堆(heap,不是数据结构中的堆,分配方式相似数据结构中的链表)内存中的地址,用于引用这个对象。
基本类型在执行环境结束时被销毁,而引用类型不会随执行环境结束而销毁,只有当全部引用它的变量不存在时这个对象才被垃圾回收机制回收,也能够由程序员分配释放。
篇幅有限就再也不跑题了,关于基本类型、引用类型、堆栈等概念请自行查阅资料。
本文为原创博客,严禁非法抄袭或复制,转载请注明出处:https://www.cnblogs.com/xiao-pengyou/