代码适用于数组,但不适用于多维数组。

时间:2015-06-15 04:29:58

标签: javascript arrays multidimensional-array

在Holdem手评估员身上工作,部分牦牛剃须正在写一个"你从7张卡中得到了多少5个组合" function(pickNofSet())。我已经做到了,但我所做的方式会带来一堆重复。

所以我必须写一个removeDuplicates()。这就是问题......它适用于一个简单的数组,但它并不适用于"数组的数组"我的" pickNofSet"功能生成。

- 这里是removeDuplicates代码 -

var removeDuplicates = function(input){ // takes array
var output = [];
for (i=0; i < input.length; i++){
    var unique = true; // all elements are innocent until proven guilty
    for(j=i+1; j < input.length; j++){
        if(input[j] === input[i]){
            unique = false; // guilty!
        };// endif
    };// end jfor
    if(unique){ // if not found guilty, 
        output.push(input[i]); // you may go free, little element
    };// end if
};// end ifor
console.log(output);
return output;  };//end function

这是我从控制台获得的内容:

> removeDuplicates(['a','b','c'],['a','b','c'],['d','e','f'],['g','h','i']);
< undefined
> removeDuplicates([1, 2, 2, 3, 3, 5, 5, 6, 6, 6]);
< [1, 2, 3, 5, 6]

2 个答案:

答案 0 :(得分:0)

运算符===无法比较数组

当您使用===检查两个元素之间的相等性时,这仅适用于原始数据类型,而不适用于数组。 e.g。

1===1 // true
[1]===[1] // Sorry, you can't

如果您希望算法同时使用原始元素和数组元素,则可能需要将等同性检查从===升级到自定义函数。

来自:

if(input[j] === input[i]){
   unique = false; // guilty!
};// endif

对此:

if (equals(input[j],input[i]){
   unique = false; // guilty!
};// endif

实现equals函数能够比较原始数据类型和数组:

function equals(a,b){
    if (typeof(a)!=typeof(b))
        return false;
    else if (typeof(a)=='object'){
        if (Object.keys(a).length != Object.keys(b).length)
            return false;
        else{
            for (var keyA of Object.keys(a)){
                if (!(keyA in b))
                    return false;
                else if (a[keyA]!==b[keyA])
                    return false;
                else
                    return true;
            }
        }
    }
    else
        return a===b;
}
  

提示:希望此解决方案也适用于JSON元素。

答案 1 :(得分:0)

以下是一个应满足您需求的通用唯一过滤器示例。需要符合ES5标准的环境。

&#13;
&#13;
(function () {
    'use strict';

    function $strictEqual(a, b) {
        return a === b;
    }

    function $isUndefined(inputArg) {
        return $strictEqual(typeof inputArg, 'undefined');
    }

    function $isPrimitive(inputArg) {
        var type = typeof inputArg;

        return type === 'undefined' || inputArg === null || type === 'boolean' || type === 'string' || type === 'number' || type === 'symbol';
    }

    function $isFunction(inputArg) {
        return typeof inputArg === 'function';
    }

    function $isDate(inputArg) {
        return Object.prototype.toString.call(inputArg) === '[object Date]';
    }

    function $isRegExp(inputArg) {
        return Object.prototype.toString.call(inputArg) === '[object RegExp]';
    }

    function $isString(inputArg) {
        return Object.prototype.toString.call(inputArg) === '[object String]';
    }

    function $isArguments(inputArg) {
        return Object.prototype.toString.call(inputArg) === '[object Arguments]';
    }

    function $getItem(object, index) {
        var item;

        if ($isString(object)) {
            item = object.charAt(index);
        } else {
            item = object[index];
        }

        return item;
    }

    var de = function (a, b, circ) {
        if (a === b) {
            return true;
        }

        var aType,
            bType,
            aIsArgs,
            bIsArgs,
            aIsPrim,
            bIsPrim,
            aCirc,
            bCirc,
            ka,
            kb,
            length,
            index,
            it;

        if ($isDate(a) && $isDate(b)) {
            return a.getTime() === b.getTime();
        }

        if ($isRegExp(a) && $isRegExp(b)) {
            return a.source === b.source &&
                a.global === b.global &&
                a.multiline === b.multiline &&
                a.lastIndex === b.lastIndex &&
                a.ignoreCase === b.ignoreCase &&
                a.sticky === b.sticky;
        }

        aIsPrim = $isPrimitive(a);
        bIsPrim = $isPrimitive(b);
        if ((aIsPrim || $isFunction(a)) && (bIsPrim || $isFunction(b))) {
            /*jslint eqeq: true */
            return a == b;
        }

        if (aIsPrim || bIsPrim) {
            return a === b;
        }

        if (a.prototype !== b.prototype) {
            return false;
        }

        if (circ.a.indexOf(a) === -1) {
            circ.a.push(a);
        } else {
            aCirc = true;
        }

        if (circ.b.indexOf(b) === -1) {
            circ.b.push(b);
        } else {
            bCirc = true;
        }

        if (aCirc && bCirc) {
            circ.cnt += 1;
        } else {
            circ.cnt = 0;
        }

        if (circ.cnt > 200) {
            throw new RangeError('Circular reference limit exceeded');
        }

        aIsArgs = $isArguments(a);
        bIsArgs = $isArguments(b);
        if ((aIsArgs && !bIsArgs) || (!aIsArgs && bIsArgs)) {
            return false;
        }

        if (aIsArgs) {
            return de(Array.prototype.slice.call(a), Array.prototype.slice.call(b), circ);
        }

        ka = Object.keys(a);
        kb = Object.keys(b);
        length = ka.length;
        if (length !== kb.length) {
            if (Array.isArray(a) && Array.isArray(b)) {
                if (a.length !== b.length) {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            ka.sort();
            kb.sort();
            for (index = 0; index < length; index += 1) {
                if (ka[index] !== kb[index]) {
                    return false;
                }
            }
        }

        for (index = 0; index < length; index += 1) {
            it = ka[index];
            if (!de($getItem(a, it), $getItem(b, it), circ)) {
                return false;
            }
        }

        aType = typeof a;
        bType = typeof b;

        return aType === bType;
    };

    if (!Object.prototype.deepEqual) {
        Object.defineProperty(Object.prototype, 'deepEqual', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function (b) {
                var a = this;

                return de(a, b, {
                    a: [],
                    b: [],
                    cnt: 0
                });
            }
        });
    }

    if (!Array.prototype.unique) {
        Object.defineProperty(Array.prototype, 'unique', {
            enumerable: false,
            configurable: true,
            writable: true,
            value: function (equalFn, thisArg) {
                var object = Object(this),
                    length,
                    index,
                    eqFn,
                    arr,
                    idx,
                    val,
                    it;

                if ($isUndefined(equalFn)) {
                    eqFn = $strictEqual;
                } else {
                    eqFn = equalFn;
                }

                if (!$isFunction(eqFn)) {
                    throw new TypeError('Argument is not a function: ' + eqFn);
                }

                arr = [];
                length = object.length >>> 0;
                for (index = 0; index < length; index += 1) {
                    if (index in object) {
                        it = $getItem(object, index);
                        val = true;
                        for (idx = 0; idx < length; idx += 1) {
                            if (idx < index && idx in object && eqFn.call(thisArg, it, $getItem(object, idx))) {
                                val = false;
                                break;
                            }
                        }

                        if (val) {
                            arr.push(it);
                        }
                    }
                }

                return arr;
            }
        });
    }
}());

var data1 = [1, 2, 2, 3, 3, 5, 5, 6, 6, 6],
    data2 = [
        ['a', 'b', 'c'],
        ['a', 'b', 'c'],
        ['d', 'e', 'f'],
        ['g', 'h', 'i']
    ],
    equals = Function.prototype.call.bind(Object.prototype.deepEqual),
    pre = document.getElementById('out');

pre.textContent = JSON.stringify(data1.unique(equals), null, 2);
pre.textContent += '\n\n';
pre.textContent += JSON.stringify(data2.unique(equals), null, 2);
&#13;
<pre id="out"></pre>
&#13;
&#13;
&#13;

相关问题