Javascript类型判断相关例题及解析

时间:2022-02-04 14:28:32

题目:

请在index.html文件中,编写arraysSimilar函数,实现判断传入的两个数组是否相似。具体需求:

1. 数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。

2. 数组的长度一致。

3. 类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window.

当以上全部满足,则返回"判定结果:通过",否则返回"判定结果:不通过"。

一、测试用例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
var result=function(){
  //以下为多组测试数据
      var cases=[{
          arr1:[1,true,null],
          arr2:[null,false,100],
          expect:true
        },{
          arr1:[function(){},100],
          arr2:[100,{}],
          expect:false
        },{
          arr1:[null,999],
          arr2:[{},444],
          expect:false
        },{
          arr1:[window,1,true,new Date(),"hahaha",(function(){}),undefined],
          arr2:[undefined,(function(){}),"okokok",new Date(),false,2,window],
          expect:true
        },{
          arr1:[new Date()],
          arr2:[{}],
          expect:false
        },{
          arr1:[window],
          arr2:[{}],
          expect:false
        },{
          arr1:[undefined,1],
          arr2:[null,2],
          expect:false
        },{
          arr1:[new Object,new Object,new Object],
          arr2:[{},{},null],
          expect:false
        },{
          arr1:null,
          arr2:null,
          expect:false
        },{
          arr1:[],
          arr2:undefined,
          expect:false
        },{
          arr1:"abc",
          arr2:"cba",
          expect:false
        }];
      
  //使用for循环, 通过arraysSimilar函数验证以上数据是否相似,如相似显示“通过”,否则"不通过",所以大家要完成arraysSimilar函数,具体要求,详见任务要求。 
      for(var i=0;i<cases.length;i++){
        if(arraysSimilar(cases[i].arr1,cases[i].arr2)!==cases[i].expect) {
          document.write("不通过!case"+(i+1)+"不正确!arr1="+JSON.stringify(cases[i].arr1)+", arr2="+JSON.stringify(cases[i].arr2)+" 的判断结果不是"+cases[i].expect);
          return false;
        }       
      }
      return true;
      
    }();
  document.write("判定结果:"+(result?"通过":"不通过"));

这个文件为testData.js。主要任务是完成arraysSimilar函数。

二、arraySimilar函数

1、我的写法

1、判断2个参数是否都是数组,不是就返回false;

2、判断2个数组长度是否一致,不是直接返回fasle;

3、新建2个临时数组temp1,temp2并初始化为0,用来存放arr1和arr2中各种类型的个数。

var temp1 = [0, 0, 0, 0, 0, 0, 0, 0];
var temp2 = [0, 0, 0, 0, 0, 0, 0, 0];

4、遍历2个arr1和arr2,每遍历一个元素,将对应类型加1。

5、完成arr1和arr2的遍历后,通过temp1.toString()和temp2.toString()是否相等得出2个数组是否相似。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE HTML>
<html>
<meta charset="utf-8">
 
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=gb18030">
  <title>Untitled Document</title>
</head>
 
<body>
  <script type="text/javascript">
  /*
   * param1 Array
   * param2 Array
   * return true or false
   */
  function arraysSimilar(arr1, arr2) {
    console.log("arr1为" + arr1);
    console.log("arr2为" + arr2);
 
    if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) {
      document.write(false + "<br/>");
      return false;
    } else if (arr1.length != arr2.length) {
      document.write(false + "<br/>");
      return false;
    }
    var temp1 = [0, 0, 0, 0, 0, 0, 0, 0];
    var temp2 = [0, 0, 0, 0, 0, 0, 0, 0];
    //初始化temp1
    for (i = 0; i < arr1.length; i++) {
      console.log("arr1的第" + i + "个值为" + arr1[i]);
      switch (jsType(arr1[i])) {
        case "String":
          temp1[0]++;
          break;
        case "Boolean":
          temp1[1]++;
          break;
        case "Number":
          temp1[2]++;
          break;
        case "Undefined":
          temp1[3]++;
          break;
        case "Null":
          temp1[4]++;
          break;
        case "Function":
          temp1[5]++;
          break;
        case "Date":
          temp1[6]++;
          break;
        case "Window":
          temp1[7]++;
          break;
      }
      console.log("arr2的第" + i + "个值为" + arr2[i]);
      //初始化temp2
      switch (jsType(arr2[i])) {
        case "String":
          temp2[0]++;
          break;
        case "Boolean":
          temp2[1]++;
          break;
        case "Number":
          temp2[2]++;
          break;
        case "Undefined":
          temp2[3]++;
          break;
        case "Null":
          temp2[4]++;
          break;
        case "Function":
          temp2[5]++;
          break;
        case "Date":
          temp2[6]++;
          break;
        case "Window":
          temp2[7]++;
          break;
      }
    }
    //判断temp1和temp2是否相等
    if (temp1.toString() === temp2.toString()) {
      document.write(true + "<br/>");
      return true;
    } else {
      document.write(false + "<br/>");
      return false;
    }
 
 
  }
  //返回参数的javascript类型
  function jsType(arg) {
    //判断字符串
    if (typeof arg == "string") {
      console.log("string");
      return "String";
    }
    //判断Boolean
    if (typeof arg == "boolean") {
      console.log("boolean");
      return "Boolean";
    }
    //判断Number
    if (typeof arg == "number") {
      console.log("Number");
      return "Number";
    }
    //判断Undefined
    if (typeof arg == "undefined") {
      console.log("Undefined");
      return "Undefined";
    }
    //判断Null(不考虑IE8以下) //看了答案发现直接=== null判断就好了
    if (Object.prototype.toString.apply(arg) == "[object Null]") {
      console.log("Null");
      return "Null";
    }
    //判断Function
    if (typeof arg == "function") {
      console.log("Function");
      return "Function";
    }
    //判断日期
    if (arg instanceof Date) {
      console.log("Date");
      return "Date";
    }
    //判断window   //看了答案发现直接=== window 判断就好了
    if (arg instanceof Window) {
      console.log("window");
      return "Window";
    }
  }
  </script>
  <script src="testData.js"></script>
</body>
 
</html>

虽然代码略粗糙,但是功能完成了。网上看了其他人的答案确实不同的人做法不一样,有些值得借鉴的地方。

2、其他答案

建一个类型对象数组obj,初始化为零,arr1遍历时每个元素对应的类型加一,arr2遍历时每个元素对应的类型减一,最终判断obj里所有键的值都为0即相似数组。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
function check(i){
    //除了function 其他的引用类型用instanceof来判定
    if(i instanceof Date){
      return 'date';
    }
    else if(i instanceof Window){
      return 'window';
    }
    // typeof可以判断基本类型(number string boolean null(typeof 返回object) undefined )和引用类型的function类型
    if(typeof i === 'number')return 'number';
    else if(typeof i === 'string')return 'string';
    else if(typeof i === 'boolean')return 'boolean';
    else if(typeof i === 'function')return 'function';
    //typeof null 返回 object
    else if(typeof i === 'object'){
      if(i === null){
        return 'null';
      }else{
        return 'object';
      }
    }
    else if(typeof i === 'undefined'){
      return 'undefined';
    }
  }
  function arraysSimilar(arr1, arr2){
    if(!arr1||!arr2){return false;}
    if(!(arr1 instanceof Array )||!(arr2 instanceof Array))return false;
    if(arr1.length!=arr2.length)return false;
    var obj={
      'number':0,
      'string':0,
      'boolean':0,
      'undefined':0,
      'null':0,
      'function':0,
      'date':0,
      'object':0,
      'window':0
        };
    for(var i=0;i<arr1.length;i++){
 
      var r1=check(arr1[i]);
      var r2=check(arr2[i]);
      obj[r1]++;
      obj[r2]--;
    }
    for(var o in obj){
      if(obj[o]!=0)return false;
    }
    return true;
 
  }

还有一个答案,差不多算标准答案,当然这种题也没有标准答案。和上个答案的差别是,用map(在js中也就是对象)存放数据类型和次数,这个map初始化为{},在后面动态生成的。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
 * String, Boolean, Number, undefined, null, 函数,日期, window
 */
function arraysSimilar(arr1, arr2) {
  // 判断参数,确保arr1, arr2是数组,若不是直接返回false
  if (!(arr1 instanceof Array)
    || !(arr2 instanceof Array)) {
    return false;
  }
 
  // 判断长度
  if (arr1.length !== arr2.length) return false;
 
  var i = 0,
    n = arr1.length,
    countMap1 = {}, // 用来计算数组元素数据类型个数的map,key是TYPES中的类型字符串,value是数字表示出现次数。
    countMap2 = {},
    t1, t2,
    TYPES = ['string', 'boolean', 'number', 'undefined', 'null',
      'function', 'date', 'window'];
 
  // 因为是无序的,用一个对象来存储处理过程。key为类型, value为该类型出现的次数。
  // 最后校验:若每一种数据类型出现的次数都相同(或都不存在),则证明同构。
  for (; i < n; i++) {
    t1 = typeOf(arr1[i]);
    t2 = typeOf(arr2[i]);
    if (countMap1[t1]) {
      countMap1[t1]++;
    } else {
      countMap1[t1] = 1;
    }
    if (countMap2[t2]) {
      countMap2[t2]++;
    } else {
      countMap2[t2] = 1;
    }
  }
 
  // 因为typeof只能判断原始类型,且无法判断null(返回"object"),所以自己写typeof方法扩展。
  function typeOf(ele) {
    var r;
    if (ele === null) r = 'null'; // 判断null
    else if (ele instanceof Array) r = 'array'; // 判断数组对象
    else if (ele === window) r = 'window'; // 判断window
    else if (ele instanceof Date) r = 'date' // 判断Date对象
    else r = typeof ele; // 其它的,使用typeof判断
    return r;
  }
 
  for (i = 0, n = TYPES.length; i < n; i++) {
    if (countMap1[TYPES[i]] !== countMap2[TYPES[i]]) {
      return false;
    }
  }
 
  return true;
}

还有一个比较简洁也好理解的解法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<script type="text/javascript"
    /*
     * param1 Array
     * param2 Array
     * return true or false
     */
    function type(a){
      return a === null ? '[object Null]':Object.prototype.toString.apply(a); //hack ie678
    }
    function arraysSimilar(arr1, arr2){
      if(!Array.isArray(arr1) || !Array.isArray(arr2) ||arr1.length!=arr2.length){return false;}
      var arr3=[];
      var arr4=[];
      var x;
      for(var i in arr1){
        arr3.push(type(arr1[i]));
        arr4.push(type(arr2[i]));
      }
      if(arr3.sort().toString()==arr4.sort().toString()){
        return true;
      }else{
        return false;
      }
    }
  </script>

还有一个精妙的解法,我对这种不感兴趣,没仔细看。

?
1
2
3
4
5
6
7
8
var global = window;
function arraysSimilar(arr1, arr2){
  return (arr1 instanceof Array && arr2 instanceof Array) && JSON.stringify(arr1.map(function(v) {
    return null === v ? "sun" : (v instanceof Date ? "heart" : (v === global ? "queen" : typeof v));
  }).sort()) === JSON.stringify(arr2.map(function(v) {
    return null === v ? "sun" : (v instanceof Date ? "heart" : (v === global ? "queen" : typeof v));
  }).sort());
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/starof/p/6370435.html