前言
之前做的一道题,现在有了一些新的想法记录一下。
题目
比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。
测试案例
- diff([1, 2, 3, 5], [1, 2, 3, 4, 5]) 应该返回
[4]
。 - diff([“diorite”, “andesite”, “grass”, “dirt”, “pink wool”, “dead shrub”], [“diorite”, “andesite”, “grass”, “dirt”, “dead shrub”]) 应该返回
["pink wool"]
。 - diff([“andesite”, “grass”, “dirt”, “dead shrub”], [“andesite”, “grass”, “dirt”, “dead shrub”]) 应该返回
[]
。 - diff([], [“snuffleupagus”, “cookie monster”, “elmo”]) 应该返回
["snuffleupagus", "cookie monster", "elmo"]
。 - diff([1, “calf”, 3, “piglet”], [7, “filly”])应该返回
[1, "calf", 3, "piglet", 7, "filly"]
。
参考答案
1.基础版
代码如下:
function diff(arr1, arr2) {
let arr3 = [];
for (let i=0;i<arr1.length;i++) {
if(arr2.indexOf(arr1[i]) === -1)
arr3.push(arr1[i]);
}
let arr4 = [];
for (let j=0;j<arr2.length;j++) {
if(arr1.indexOf(arr2[j]) === -1)
arr4.push(arr2[j]);
}
// console.log("diff:", arr3.concat(arr4)) //测试结果
return arr3.concat(arr4);
}
2.升级版
代码如下:
function diff(arr1, arr2) {
for (let i = 0; i < arr2.length;) {
if (arr1.indexOf(arr2[i]) > -1) {
arr1.splice(arr1.indexOf(arr2[i]), 1);
arr2.splice(i, 1);
} else {
i++;
}
}
console.log("diff:", arr1.concat(arr2)) //测试结果
return arr1.concat(arr2);
}
总结
- 基础版对于稍有认知的coder都会写,是一种很直接的写法。就是新建两个空数组,将传进来的两个数组分别作为对照组进行比对并将对照组中不存在的元素存入到一个空白数组中,经过两次
for循环
后两个空白数组就分别填充了两个原始数组的独特元素,然后合并返回即可。 - 升级版主要是利用
splice()
方法对于有重复直接剔除,剩下的合并返回即可。但是在实现的时候出了很多问题,如下:- 首先我考虑了哪个数组长,以长数组为对照组,遍历短数组,后来发现没必要。无论arr1和arr2哪个长都是一样的。
- 采用
splice()
方法就是因为它可以直接剔除原数组中的内容,但是运行时发现结果总是不对,后来发现因为splice()
是即时生效的不会等你for循环走完的时候再剔除。这就导致使用for (let i=0;i<arr1.length;i++)
这种形式的for循环中i
在一直递增,如果有剔除项,在发生剔除之后的循环都会混乱,再剔除arr[i]
的时候已经不是最初的arr[i]
了。 - 后来考虑再声明两个变量
arr3=arr1
和arr4=arr2
,但是因为数组
和对象
这两种数据类型在=
赋值的时候并不是将右边的值给了左边,而是将右边值的 地址 给了左边。所以在修改arr3
和arr4
的时候arr1
和arr2
依然会改变。 - 最后我想出了这个办法,就是当有剔除项产生的时候不让
i
递增,这样保证下次的arr[i]
依然正常。
- 至此完满解决,各位如果有好的想法可以评论交流。