everycode icon indicating copy to clipboard operation
everycode copied to clipboard

2014年12月1日 D5

Open nunnly opened this issue 10 years ago • 8 comments
trafficstars

题目

写一个函数来判断传入的两个数组是否相似。具体需求:

当以下全部满足,则返回true,否则返回false

  1. 数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。
  2. 数组的长度一致。
  3. 类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window.

接口

/*
 * param1 Array 
 * param2 Array
 * return true or false
 */
function arraysSimilar(arr1, arr2){

}

判断

// 执行以下代码得到判断结果 by @酱油
var result = function() {
var cases = [
// case 1, 基本case
{arr1 : [1, true, null], arr2 : [null, false, 100], expect : true},
// case2, function区分
{arr1 : [function(){}, 100], arr2 : [100, {}], expect : false},
// case3, null区分
{arr1 : [null, 999], arr2 : [{}, 444], expect : false},
// case4, 应该相等的全类型乱序case
{
    arr1 : [window, 1, true, new Date(), "hahaha", (function(){}), undefined], 
    arr2 : [undefined, (function(){}), "okokok", new Date(), false, 2, window], 
    expect : true
},
// case5, Date()区分
{arr1 : [new Date()], arr2:[{}], expect:false},
// case6, window区分
{arr1 : [window], arr2:[{}], expect: false},
// case7, undefined / null 区分
{arr1 : [undefined, 1], arr2: [null, 2], expect : false},
// case8, 奇葩case
{arr1 : [new Object, new Object, new Object], arr2: [{}, {}, null], expect : false},
// case9, 边界1
{arr1 : null, arr2 : null, expect : false},
// case10, 边界2
{arr1 : [], arr2 : undefined, expect : false},
// case11, 边界3
{arr1 : "abc", arr2: "cba", expect: false}
];
for (var i = 0; i < cases.length; i++) {
    if (arraysSimilar(cases[i].arr1, cases[i].arr2) !== cases[i].expect) {
        console.error('不通过!case' + (i + 1) + '不正确!arr1:' + cases[i].arr1.toString() + ', arr2:' + cases[i].arr2.toString() + ' 的结果不是' + cases[i].expect);
        return false;
    }
}

return true;
}();
console.log('判定结果:' + (result ? '通过' : '不通过'));

nunnly avatar Dec 01 '14 02:12 nunnly

通过 by @酱油

运行结果:http://ideone.com/SSOVDh

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

不想 var 变量,不想 if,所以本来能更短的,把两个 map 函数声明成一个就好了。

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

再压一下,貌似还能压

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

不要打我 -。 -

function arraysSimilar(a1,a2){function f(v){return null===v?"1":(v instanceof Date?"2":(v===global?"3":typeof v));}
var j=JSON.stringify;return(a1 instanceof Array&&a2 instanceof Array)&&j(a1.map(f).sort())===j(a2.map(f).sort());}

XadillaX avatar Dec 01 '14 03:12 XadillaX

源代码-通过 by @酱油

function arraysSimilar(arr1, arr2){
    var obj_toString = Object.prototype.toString;
    if(!arr1 || !arr2 || obj_toString.apply(arr1) !== "[object Array]" || obj_toString.apply(arr2) !== "[object Array]")
        return false;
    if(arr1.length !== arr2.length)
        return false;
    var map1 = {}, property1,
        map2 = {}, property2,
        i, property, 
        size = arr1.length;     

    for(i = 0; i<size; i++) {
        var property1 = obj_toString.apply(arr1[i]);
        var property2 = obj_toString.apply(arr2[i]);
        if(map1[property1])
            map1[property1] = map1[property1] + 1;
        else
            map1[property1] = 1;

        if(map2[property2])
            map2[property2] = map2[property2] + 1;
        else
            map2[property2] = 1;
    }

    for( property in map1 ) {
        if(!map2[property] || map2[property] !== map1[property])
            return false;
    }
    return true;
}
待压缩

businiaowa avatar Dec 01 '14 03:12 businiaowa

源代码 - 通过 by @酱油

/**
 * String, Boolean, Number, undefined, null, 函数,日期, window
 */
function arraysSimilar(arr1, arr2) {
    // 判断边界
    if (!(arr1 instanceof Array)
        || !(arr2 instanceof Array)) {
        return false;
    }

    // 判断长度
    if (arr1.length !== arr2.length) return false;

    var i = 0, 
        n = arr1.length, 
        countMap1 = {}, 
        countMap2 = {},
        t1, t2,
        TYPES = ['string', 'boolean', 'number', 'undefined', 'null',
            'function', 'date', 'window'];

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

    function typeOf(ele) {
        var r;
        if (ele === null) r = 'null';
        else if (ele instanceof Array) r = 'array';
        else if (ele === window) r = 'window';
        else if (ele instanceof Date) r = 'date'
        else r = typeof ele;
        return r;
    }

    for (i = 0, n = TYPES.length; i < n; i++) {
        if (countMap1[TYPES[i]] !== countMap2[TYPES[i]]) {
            return false;
        }
    }

    return true;
}

压缩后

function arraysSimilar(arr1,arr2){if(!(arr1 instanceof Array)||!(arr2 instanceof Array)){return false;}
if(arr1.length!==arr2.length)return false;var i=0,n=arr1.length,countMap1={},countMap2={},t1,t2,TYPES=['string','boolean','number','undefined','null','function','date','window'];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;}}
function typeOf(ele){var r;if(ele===null)r='null';else if(ele instanceof Array)r='array';else if(ele===window)r='window';else if(ele instanceof Date)r='date'
else r=typeof ele;return r;}
for(i=0,n=TYPES.length;i<n;i++){if(countMap1[TYPES[i]]!==countMap2[TYPES[i]]){return false;}}
return true;}

745字符(好像最啰嗦的方案了吧。。。哇咔咔)

Bosn avatar Dec 01 '14 03:12 Bosn

通过 by @酱油

function arraysSimilar(arr1, arr2){

    if(toType(arr1) !== "[object Array]" || toType(arr2) !== "[object Array]"){

        return false;
    }

    return toTypeString(arr1).sort() + "" === toTypeString(arr2).sort() + "";

    function toTypeString(arr){ 
        return arr.map(function(item, index, array){
            return toType(item);
        });
    }

    function toType(obj){
        return ({}).toString.call(obj);
    }   
}

Runsing avatar Dec 01 '14 03:12 Runsing

通过 by @酱油

    function arraysSimilar(arr1, arr2) {
        var toObjType = function(item) {return ({}).toString.call(item);}
        var toSort = function(a, b) {return a < b}

        if ((toObjType(arr1) !== '[object Array]' || toObjType(arr2) !== '[object Array]') || arr1.length !== arr2.length) {
            return false;
        }

        return (arr1.map(toObjType).sort(toSort) + '') === (arr2.map(toObjType).sort(toSort) + '');
    }

终于通过了!!

think2011 avatar Dec 01 '14 04:12 think2011

源代码 - 通过 by @酱油

受 @think2011 启发

function arraysSimilar(a1, a2) {
    function f(v) {
        return ({}).toString.call(v);
    }
    return (a1 instanceof Array && a2 instanceof Array) && a1.map(f).sort() + "" === a2.map(f).sort() + "";
}

压缩后:

function arraysSimilar(a,b){function c(a){return{}.toString.call(a)}return a instanceof Array&&b instanceof Array&&a.map(c).sort()+""==b.map(c).sort()+""}

XadillaX avatar Dec 01 '14 06:12 XadillaX

源代码 - 通过 by @酱油

function arraysSimilar(arr1, arr2){
    function getType(o){
        return Object.prototype.toString.call(o);
    }
    if(getType(arr1) != "[object Array]" || getType(arr2) != "[object Array]"){
        return false
    }
    var bosn1 = arr1.slice().sort(function(a,b){
        return getType(a) === getType(b) ? 0 : getType(a) > getType(b) ? 1 : -1
    })
    var bosn2 = arr2.slice().sort(function(a,b){
        return getType(a) === getType(b) ? 0 : getType(a) > getType(b) ? 1 : -1
    })
    for(var i=0;i<bosn1.length;i++){
        if(getType(bosn1[i]) != getType(bosn2[i])){return false};
    }
    return true;
}

逗B~@Bosn

nunnly avatar Dec 02 '14 01:12 nunnly

以上全部通过,谢谢大家的参与!

Bosn avatar Dec 02 '14 02:12 Bosn