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());
}