patternjavascriptMinor
Take from top, evaluate, put on bottom
Viewed 0 times
toptakeputbottomevaluatefrom
Problem
In this example, I am only looking for the first duplicate - curious if this logic in for loop (take from the top, evaluate, put on the bottom) pattern has a standard form
function findOneDupe(input){
var b = input.split(/\s|\n/).map(Number);
b.shift();
for (var i=0;i<b.length;i++){
var e = b.shift();
if (b.indexOf(e) == -1) return e;
b[b.length] = e;
}
return -1;
}Solution
function findOneDupe(input){You name this function
findOneDupe, but this code finds the first element that is not duplicated. function findFirstUnique(input) {Now it does what it says, not the opposite of what it says.
var b = input.split(/\s|\n/).map(Number);Why call this
b? That gives me no idea what it holds. var tokens = input.split(/\s|\n/).map(Number);The name
tokens is far more understandable in terms of whitespace delineated text. b.shift();Why? Presumably you have some cruft to remove from the array. Comment this and explain why it needs to be done. Then you don't have to worry about someone optimizing it out later.
for (var i=0;i<b.length;i++){
var e = b.shift();
if (b.indexOf(e) == -1) return e;
b[b.length] = e;
}This seems more complicated than it needs to be. You are both maintaining an index variable and removing from the array. Why not pick one or the other?
for (var i=0; i < tokens.length; i++) {
if (tokens.indexOf(tokens[i], i+1) == -1 && tokens.indexOf(tokens[i]) == i) {
return tokens[i];
}
}Now we don't add or remove from the array at all. Which is good, since Javascript arrays are not lists. Removing and adding can cause the array to not fit its memory allocation anymore. When that happens, the array will be copied into a new memory location. Pure waste considering that you never use the array outside this function.
Note that the two
indexOf checks will never check more elements than your single check. The first one only checks things after i and the second one only checks up to i (because it always finds at i). Note that this takes \$O(n^2)\$ time in the worst case, as you loop over every element and search the array for it. You can get better asymptotic performance by sorting the array.
tokens.sort();
var i = 1;
while (i < tokens.length) {
if (tokens[i-1] != tokens[i]) {
return tokens[i-1];
}
do {
i++;
} while (tokens[i-1] == tokens[i] && i < tokens.length);
// we want to get all the way past anything equal
// to the original tokens[i-1] value
i++;
}This takes \$O(n \log n)\$ time for the
sort and linear time to find any unique elements.Code Snippets
function findOneDupe(input){function findFirstUnique(input) {var b = input.split(/\s|\n/).map(Number);var tokens = input.split(/\s|\n/).map(Number);for (var i=0;i<b.length;i++){
var e = b.shift();
if (b.indexOf(e) == -1) return e;
b[b.length] = e;
}Context
StackExchange Code Review Q#129647, answer score: 7
Revisions (0)
No revisions yet.