Examples and Analysis of Javascript Type Judgment

  • 2021-08-09 06:53:40
  • OfStack

Title:

Please write the arraysSimilar function in the index. html file to judge whether the two arrays passed in are similar. Specific needs:

1. The members in the array are of the same type, and the order can be different. For example, [1, true] is similar to [false, 2].

2. The length of the array is 1.

3. The judgment range of types needs to be distinguished: String, Boolean, Number, undefined, null, function, date and window.

When all the above are satisfied, "Judgment result: passed" will be returned, otherwise, "Judgment result: not passed" will be returned.

1. Test cases


var result=function(){
  // The following are multiple sets of test data 
      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
        }];
      
  // Use for Cycle ,  Pass arraysSimilar Function to verify that the above data are similar, such as "pass" , Otherwise " Do not pass ", So everyone has to finish arraysSimilar Function , For specific requirements, please refer to the task requirements for details.   
      for(var i=0;i<cases.length;i++){
        if(arraysSimilar(cases[i].arr1,cases[i].arr2)!==cases[i].expect) {
          document.write(" Don't pass! case"+(i+1)+" Incorrect! arr1="+JSON.stringify(cases[i].arr1)+", arr2="+JSON.stringify(cases[i].arr2)+"  The judgment result is not "+cases[i].expect);
          return false;
        }        
      }
      return true;
      
    }();
  document.write(" Judgment result :"+(result?" Pass ":" Do not pass "));

This file is testData. js. The main task is to complete the arraysSimilar function.

2. arraySimilar function

1. My writing

1. Judge whether the two parameters are arrays or not, and return false;

2. Judge whether the length of the two arrays is 1, instead of directly returning fasle;;

3. Create two temporary arrays temp1 and temp2 and initialize them to 0, which are used to store the numbers of various types in arr1 and arr2.

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

4. Traverse two arr1 and arr2, and add 1 to the corresponding type every time you traverse one element.

5. After completing the traversal of arr1 and arr2, whether the two arrays are similar can be obtained by whether temp1.toString () and temp2.toString () are equal.


<!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 For " + arr1);
    console.log("arr2 For " + 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];
    // Initialization temp1
    for (i = 0; i < arr1.length; i++) {
      console.log("arr1 The first part of " + i + " The value is " + 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 The first part of " + i + " The value is " + arr2[i]);
      // Initialization 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;
      }
    }
    // Judge temp1 And temp2 Whether it is equal or not 
    if (temp1.toString() === temp2.toString()) {
      document.write(true + "<br/>");
      return true;
    } else {
      document.write(false + "<br/>");
      return false;
    }


  }
  // Returns the of the parameter javascript Type 
  function jsType(arg) {
    // Judgment string 
    if (typeof arg == "string") {
      console.log("string");
      return "String";
    }
    // Judge Boolean
    if (typeof arg == "boolean") {
      console.log("boolean");
      return "Boolean";
    }
    // Judge Number
    if (typeof arg == "number") {
      console.log("Number");
      return "Number";
    }
    // Judge Undefined
    if (typeof arg == "undefined") {
      console.log("Undefined");
      return "Undefined";
    }
    // Judge Null( Don't consider IE8 The following ) // Read the answer and find it direct === null Just judge 
    if (Object.prototype.toString.apply(arg) == "[object Null]") {
      console.log("Null");
      return "Null";
    }
    // Judge Function
    if (typeof arg == "function") {
      console.log("Function");
      return "Function";
    }
    // Judgment date 
    if (arg instanceof Date) {
      console.log("Date");
      return "Date";
    }
    // Judge window   // Read the answer and find it direct === window  Just judge 
    if (arg instanceof Window) {
      console.log("window");
      return "Window";
    }
  }
  </script>
  <script src="testData.js"></script>
</body>

</html>

Although the code is slightly rough, the function is completed. People who read other people's answers on the Internet are really different, and there are some places worth learning from.

2. Other answers

Build an array of type objects obj, initialize it to zero, arr1 passes through the corresponding type of each element plus 1, arr2 passes through the corresponding type of each element minus 1, and finally judge that the values of all keys in obj are 0, that is, similar arrays.


function check(i){
    // Except for function  Other reference types use the instanceof To judge 
    if(i instanceof Date){
      return 'date';
    }
    else if(i instanceof Window){
      return 'window';
    }
    // typeof You can judge the basic type (number string boolean null(typeof  Return object) undefined ) And reference type function Type 
    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  Return  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;

  }

There is another answer, which is almost a standard answer. Of course, there is no standard answer for this kind of question. The difference from the previous answer is that the data type and number are stored with map (in js, that is, objects), which is initialized to {} and dynamically generated later.


/**
 * String, Boolean, Number, undefined, null,  Function, date , window
 */
function arraysSimilar(arr1, arr2) {
  //  Determine parameters and ensure that arr1, arr2 Is an array, if it is not returned directly false
  if (!(arr1 instanceof Array)
    || !(arr2 instanceof Array)) {
    return false;
  }
 
  //  Judgment length 
  if (arr1.length !== arr2.length) return false;
 
  var i = 0, 
    n = arr1.length, 
    countMap1 = {}, //  Used to calculate the number of data types of array elements map , key Yes TYPES The type string in the, value Is a number indicating the number of occurrences. 
    countMap2 = {},
    t1, t2,
    TYPES = ['string', 'boolean', 'number', 'undefined', 'null',
      'function', 'date', 'window'];
 
  //  Because it is disorderly, use 1 Objects to store the processing. key Is a type , value Is the number of occurrences of this type. 
  //  Final check: if every 1 If all the data types occur the same number of times (or none of them exist), isomorphism is proved. 
  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;
    }
  }
 
  //  Because typeof Only the original type can be judged, and it cannot be judged null( Return "object") , so write it yourself typeof Method extension. 
  function typeOf(ele) {
    var r;
    if (ele === null) r = 'null'; //  Judge null
    else if (ele instanceof Array) r = 'array'; //  Judge array object 
    else if (ele === window) r = 'window'; //  Judge window
    else if (ele instanceof Date) r = 'date' //  Judge Date Object 
    else r = typeof ele; //  Others, use typeof Judge 
    return r;
  }
 
  for (i = 0, n = TYPES.length; i < n; i++) {
    if (countMap1[TYPES[i]] !== countMap2[TYPES[i]]) {
      return false;
    }
  }
 
  return true;
}

There is also a more concise and understandable solution


<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>

There is also a subtle solution, which I am not interested in and have not looked at carefully.


var global = window;
function arraysSimilar(arr1, arr2){
  return (arr1 instanceof Array && arr2 instanceof Array) && JSON.stringify(arr1.map(function(v) {
    return null === v ? "☀" : (v instanceof Date ? "❤" : (v === global ? "❀" : typeof v));
  }).sort()) === JSON.stringify(arr2.map(function(v) {
    return null === v ? "☀" : (v instanceof Date ? "❤" : (v === global ? "❀" : typeof v));
  }).sort());
}

Related articles: