使用reduce方法消除任何重复的数字

时间:2015-06-20 12:26:47

标签: javascript reduce higher-order-functions

我正在尝试使用如下的reduce方法来消除重复,但是,它不是很有效:

var unique = function(array) {
array = array.sort(function(a,b) {return a-b;}); 
var noDup = [array[0]];
array.reduce(function(c,d) {
     if(c!==d) {
        noDup.push(d);
        return d;
     }
 });
return noDup;
};
var x = [9,2,1,5,9,1,1,4,2,9];//==>[1, 1, 2, 4, 5, 9, 9]

2 个答案:

答案 0 :(得分:3)

function unique(values) {
    return values.reduce(function(prev, cur) {
        if (prev.indexOf(cur) == -1) {
            prev.push(cur);
        }

        return prev;
    }, []);
}

unique([9,2,1,5,9,1,1,4,2,9]) // --> [9, 2, 1, 5, 4]

fiddle

答案 1 :(得分:2)

您正在使用"中间值" reduce保留前一个值,以便您可以在下次检查时对其进行检查。但是这使你无法计算你想要的真正中间值,这是你正在构建的唯一数组,所以你必须在外面声明它(noDup),这样会破坏整个目的。然后,您的代码存在诸如未向reduce提供初始值等问题。在这种情况下,reduce有一个特殊的行为,即它使用数组的前两个值调用回调;你处理不当的情况。

无论如何,因为你似乎愿意对数组进行排序,所以你可以避免每次循环都做indexOf,只需记住前一个值并检查它:

function unique(values) {
    var prev;
    return values . sort() . reduce(function(result, cur) {
        if (cur !== prev) result.push(cur);
        prev = cur;
        return result;
    }, []);
}

但实际上我们并不需要保持prev的价值;相反,我们可以简单地直接引用前一个元素,因为filter将索引和数组的其他参数传递给回调,所以:

function unique(values) {
    return values . sort() . reduce(function(result, cur, index, array) {
        if (cur !== array[index-1]) result.push(cur);
        return result;
    }, []);
}

但是如果你考虑一下,这只不过是使用reduce编写的过滤器。它只是过滤掉与前一个相同的数字。所以只需将其作为过滤器开头:

function unique(values) {
    return values . sort() . filter(value, i, arr) { return value !== arr[i-1]; });
}

还有其他方法可以使用不需要排序的过滤器来删除重复项。这是一个简单的问题:

values . filter(function(value, i, arr) { return arr.indexOf(value) === i; });

这就是说,如果在数组中首次找到它的位置是它的位置,则过滤掉一个数字。换句话说,过滤出数组中较早出现的数字。