I have an array
var aos = ["a","a","a","b","b","c","d","d"];
I want to know if I can remove just 1 item if it finds 2 or more of the same value in the array. So for instance if it finds
"a", "a"
it will remove one of those "a"
This i开发者_如何学运维s my current code:
var intDennis = 1;
for (var i = 0; i < aos.length; i++) {
while (aos[i] == aos[intDennis]) {
aos.splice(i, 1);
intDennis++;
console.log(aos[intDennis], aos[i]);
}
intDennis = 1;
}
NOTE: My array is sorted.
Edited after better understanding of OP use-case. Updated solution and fiddle test to incorporate suggestion from pst in comments.
(Not for nothing, but this method does not require the original array be sorted.)
Try this...
var elements = [];
var temp = {};
for (i=0; i<aos.length; i++) {
temp[aos[i]] = (temp[aos[i]] || 0) + 1;
}
for (var x in temp) {
elements.push(x);
for (i=0; i<temp[x]-2; i++) {
elements.push(x);
}
}
Fiddle Test
Because you said you have a sorted array, you only need to remove the second time a element is found. You only need one for.
The splice()
function returns the removed element so, just use it to not remove more elements of that kind.
This solution is more clean and efficient.
var aos = ["a","a","a","b","b","c","d","d"];
var lastRemoved = "";
for (var i = 1; i < aos.length; i++) {
if (aos[(i-1)] == aos[i] && lastRemoved != aos[i]) {
lastRemoved = aos.splice(i, 1);
}
}
Code tested and working. Result: ["a", "a", "b", "c", "d"]
I don't believe there's any better way to do this on an unsorted array than an approach with O(n^2) behaviour. Given ES5 array-builtins (supported in all modern browsers, though not in IE prior to IE9), the following works:
aos.filter(function(value, index, obj) { return obj.indexOf(value) === index; })
UPDATED ANSWER TO REMOVE ONLY 1 DUPLICATE:
Assuming that each object will resolve to a unique String, here's a potential solution. The first time the object is detected, it sets a counter for that object to one. If it finds that object again, it splices that element out and increments the associated counter. If it finds that element more times, it will leave it alone.
var elements = {};
for (var i = 0; i < aos.length; i++) {
if(elements[aos[i]]){
if(elements[aos[i]] == 1){
aos.splice(i,1);//splice the element out of the array
i--;//Decrement the counter to account for the reduced array
elements[aos[i]]++;//Increment the count for the object
}
} else {
elements[aos[i]] = 1;//Initialize the count for this object to 1;
}
}
Here's the test fiddle for this.
I would not mutate the input -- that is, don't use splice
. This will simplify the problem a good deal. Using a new array object here may actually be more efficient. This approach utilizes the fact that the input array is sorted.
Consider: (jsfiddle demo)
var input = ["a","a","a","b","b","c","d","d"]
var result = []
for (var i = 0; i < input.length; i++) {
var elm = input[i]
if (input[i+1] === elm) {
// skip first element (we know next is dup.)
var j = i + 1
for (; input[j] === elm && j < input.length; j++) {
result.push(input[j])
}
i = j - 1
} else {
result.push(elm)
}
}
alert(result) // a,a,b,c,d
Happy coding.
Replace ===
with a custom equality, as desired. Note that it is the first item is omitted from the output, which may not always be "correct".
REVISED EXAMPLE
function removeDuplicate(arr) {
var i = 1;
while(i < arr.length) {
if(arr[i] == arr[i - 1]) {
arr.splice(i, 1);
}
while(arr[i] == arr[i - 1] && i < arr.length) {
i += 1;
}
i += 1;
}
return arr;
}
alert(removeDuplicate(["a","a","a","b","b","c","d","d"]));
精彩评论