2015-06-20 2 views
0

Я пытаюсь использовать метод уменьшения следующим образом для устранения дубликатов, однако, это не совсем рабочий:Используя метод сокращения для устранения дублирующихся номеров

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] 
+0

Почему 'return d;'? – Bergi

ответ

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; 
    }, []); 
} 

Но если вы думаете об этом, это не что иное, как фильтр, записанного с помощью уменьшить. Это просто отфильтровывает номера, которые совпадают с предыдущими. Так что просто написать его в качестве фильтра, чтобы начать с:

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

Это говорит о том, отфильтровывать номер, если место, где он впервые найден в массиве является его местоположение. Другими словами, отфильтруйте числа, которые встречаются ранее в массиве.

+0

У меня просто вопрос о вашем первом подходе. Вы использовали 'if (cur! == prev) result.push (cur);' но прев не был даже объявлен. как это работает, я обычно получаю ошибки, когда я это делаю, я знаю, что это старый пост, но просто интересно – daddycardona

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

Смежные вопросы