I know that you can remove 1 of the duplicate number out of an array but is there a way you can remove the number if they're duplicate? So far, below code is what I have. I wanted to use for loop to remove the number out of the array if they're equal, but I dont think I coded it correctly or it's not complete. I want it to return [3, 4, 5]
function sym(args) {
var array = [];
var join;
for(var i = 0; i < arguments.length; i++){
array.push(arguments[i]);
join = array[0].concat(array[1]);
}
join.sort();
for(var j = 0; j < join.length; j++) {
if(join[j] === join[j+1]) {
var removed = join.splice(j, join[j+2]);
console.log(removed);
}
}
return join;
}
sym([1, 2, 3], [5, 2, 1, 4]);
Here's my take
function sym() {
var vals = {};
var rarray= [];
var a=arguments;
for (var i=0,l=a.length;i<l;i++) {
if (a[i] instanceof Array) {
for (var n=0,ln=a[i].length;n<ln;n++) {
vals[a[i][n]]=vals[a[i][n]]||[];
vals[a[i][n]].push(a[i][n]);
}
}
}
for (var i in vals) {
if (vals.hasOwnProperty(i)) {
if (vals[i].length===1)
rarray.push(i);
}
}
return rarray;
}
Examples:
sym([1, 2, 3], [5, 2, 1, 4]);
// return: ["3", "4", "5"]
sym([1, 2, 3], [5, 2, 1, 4],[4,6,7,8],[8,4]);
// ["3", "5", "6", "7"]
sym([1,2],[1]);
// return: ["2"]
var sym = function (ar1, ar2) {
return ar1
.concat(ar2)
.sort(function (a, b) { return a - b; })
.filter(function (elem, i, ar) {
return ar[i-1] !== elem && ar[i+1] !== elem;
});
}
I like Crayon Violent's solution, but I don't see the point in maintaining arrays of duplicate items when you can simply count them.
This provides a large performance increase (jsperf), while also simplifying the code.
function sym() {
var occurrences = {};
var inputArrays = arguments;
var uniqueItems = [];
function addOccurrences(arr) {
for (var i = 0, len=arr.length; i < len; i++) {
occurrences[arr[i]] = 1 + (occurrences[arr[i]] || 0);
}
}
for (var i=0, len=inputArrays.length; i < len; i++) {
if (inputArrays[i] instanceof Array) {
addOccurrences(inputArrays[i]);
}
}
for (var item in occurrences) {
if (occurrences[item] === 1) {
uniqueItems.push(item);
}
}
return uniqueItems;
}
Which can be made nicer if you happen to have underscore or lodash in your project:
function sym() {
var inputArrays = _.filter(arguments, _.isArray);
var occurrences = {};
function addOccurrences(arr) {
_.forEach(arr, function(item){
occurrences[item] = 1 + (occurrences[item] || 0);
});
}
_.forEach(inputArrays, addOccurrences);
// Select the items with one occurence, return the keys (items)
return _.filter(_.keys(occurrences), function(item){
return occurrences[item] === 1;
});
}
Related
I am trying to filter out elements in arr that are equal to the input arguments. I was wondering why this wouldn't work.
function destroyer(arr) {
// Remove all the values
var newarr = arr.slice();
var i = 1;
while (i < arguments.length){
newarr = newarr.filter(function(num){
if (num == arguments[i]){
return (false);
}
return (true);
});
i++;
}
return newarr;
}
destroyer([3, 5, 1, 2, 2], 2, 3, 5);
should return [1];
The way I solved it was using splice() instead:
function destroyer(arr) {
var i = 1;
while (i < arguments.length){
var j = 0;
while (j < arr.length){
if (arr[j] == arguments[i]){
arr.splice(j,1);
j = j;
}
else
j++;
}
i++;
}
return arr;
}
The root cause of this problem is: in the following code:
newarr = newarr.filter(function(num){
if (num == arguments[i]){
return (false);
}
return (true);
});
The arguments is not what you expected. arguments here refer to the parameters of function(num){..., not the parameters of destroyer(arr).
To fix the problem, you can retrieve the interested number before newarr.filter:
function destroyer(arr) {
// Remove all the values
var newarr = arr.slice();
var i = 1;
while (i < arguments.length){
var interested = arguments[i];
newarr = newarr.filter(function(num){
if (num == interested){
return (false);
}
return (true);
});
i++;
}
return newarr;
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5));
You can do it in simpler way
function destroyer() {
let args = Array.from(arguments); // Create new array from the arguments
args.shift(); // remove first element from the arguments
return arguments[0].filter( item => !args.includes(item) ); //Doing filter
}
console.log(destroyer([3, 5, 1, 2, 2], 2, 3, 5)); // [1]
Is there a specific reason you are not using Array.prototype.filter?
For example:
const elements = [1, 2, 3, 4, 5, 6];
const filterInput = inputs => element => !inputs.includes(element);
const filteredElements = elements.filter(filterInput([1, 5, 6]));
console.log(filteredElements);
It's because you use arguments variable in another function,
if (num == arguments[i]){ the arguments variable that's here is actullay arguments list of second function.
function(num){
if (num == arguments[i]){
return (false);
}
return (true);
}
to fix this problem try this:
function destroyer(arr) {
var i = 1,
args = arguments;
while (i < arguments.length){
var j = 0;
while (j < arr.length){
if (arr[j] == args[i]){
arr.splice(j,1);
j = j;
}
else
j++;
}
i++;
}
return arr;
}
I have a question . How do you retrieve elements that has no double value in an array?? For example: [1,1,2,2,3,4,4,5] then you retrieve [3,5] only.
Thanks in advance
for (var j = 0; j < newArr.length; j++) {
if ((arr1.indexOf(newArr[j]) === 0) && (arr2.indexOf(newArr[j]) === 0)) {
index = newArr.indexOf(j); newArr.splice(index, 1);
}
}
If the item in the array is unique then the index found from the beginning should equal the index found from the end, in other words:
var xs = [1, 1, 2, 2, 3, 4, 4, 5];
var result = xs.filter(function(x) {
return xs.indexOf(x) === xs.lastIndexOf(x);
});
console.log(result); //=> [3, 5]
sorry for the presentation its my first post !
You have to compare each element of your array to the others in order to get the number of occurence of each element
var tab = [1,1,2,2,3,4,4,5] //The array to analyze
tab = tab.sort(); // we sort the array
show(tab); // we display the array to the console (F12 to open it)
var uniqueElementTab = []; // this array will contain all single occurence
var sameElementCounter = 0;
for(x=0;x<tab.length;x++){ // for all element in the array
sameElementCounter = 0;
for(y=0;y<tab.length;y++){ // we compare it to the others
if((tab[x]==tab[y])){
sameElementCounter+=1; // +1 each time we meet the element elsewhere
}
}
if(sameElementCounter<=1){
uniqueElementTab.push(tab[x]); //if the element is unique we add it to a new array
}
}
show(uniqueElementTab); // display result
function show(tab) { // Simple function to display the content of an array
var st="";
for(i=0;i<tab.length;i++){
st += tab[i]+" ";
}
console.log(st+"\n");
}
Hope it helps.
Here is a simple "tricky" solution using Array.sort, Array.join, Array.map, String.replace and String.split functions:
var arr = [1, 1, 2, 2, 3, 4, 4, 5];
arr.sort();
var unique = arr.join("").replace(/(\d)\1+/g, "").split("").map(Number);
console.log(unique); // [3, 5]
create new array tmp,and check already value exist by indexOf .If existed delete by splice function..
var arr = [1,1,2,2,3,4,4,5];
var tmp = [];
var dup = [];
for(var i = 0; i < arr.length; i++){
var ind = tmp.indexOf(arr[i]);
if(ind == -1){
if(dup.indexOf(arr[i]) == -1){
tmp.push(arr[i]);
}
}
else{
tmp.splice(ind,1);
dup.push(arr[i]);
}
}
console.log(tmp);
This would be my way of doing this job.
var arr = [1,1,2,2,3,4,4,5],
uniques = Object.keys(arr.reduce((p,c) => (c in p ? Object.defineProperty(p, c, {enumerable : false,
writable : true,
configurable : true})
: p[c] = c,
p), {}));
console.log(uniques);
A solution for unsorted arrays with a hash table for the items. Complexity O(2n)
var array = [1, 1, 2, 2, 3, 4, 4, 5, 1],
hash = Object.create(null),
single;
array.forEach(function (a, i) {
hash[a] = a in hash ? -1 : i;
});
single = array.filter(function (a, i) {
return hash[a] === i;
});
console.log(single);
If the array is sorted, you can solve this in O(n) (see "pushUniqueSinglePass" below):
function pushUniqueSinglePass(array, unique) {
var prev; // last element seen
var run = 0; // number of times it has been seen
for (var i = 0; i < array.length; i++) {
if (array[i] != prev) {
if (run == 1) {
unique.push(prev); // "prev" appears only once
}
prev = array[i];
run = 1;
} else {
run++;
}
}
}
function pushUniqueWithSet(array, unique) {
var set = new Set();
for (var i = 0; i < array.length; i++) {
set.add(array[i]);
}
for (let e of set) {
unique.push(set);
}
}
// Utility and test functions
function randomSortedArray(n, max) {
var array = [];
for (var i = 0; i < n; i++) {
array.push(Math.floor(max * Math.random()));
}
return array.sort();
}
function runtest(i) {
var array = randomSortedArray(i, i / 2);
var r1 = [],
r2 = [];
console.log("Size: " + i);
console.log("Single-pass: " + time(
pushUniqueSinglePass, array, r1));
console.log("With set: " + time(
pushUniqueWithSet, array, r2));
// missing - assert r1 == r2
}
[10, 100, 1000, 10000,
100000, 1000000
].forEach(runtest);
function time(fun, array, unique) {
var start = new Date().getTime();
fun(array, unique);
return new Date().getTime() - start;
}
This is much more efficient than using maps or sorting (time it!). In my machine, a 1M sorted array can have its unique elements found in 18 ms; while the version that uses a set requires 10x more.
This question already has answers here:
Get all non-unique values (i.e.: duplicate/more than one occurrence) in an array
(97 answers)
Closed 8 years ago.
I'm looking for an easy way of removing a duplicate value from an array. I figured out how to detect if there is a duplicate or not, just I don't know how to "push" it from the value. For example, if you go to the link provided, and then type, "abca" (press return/enter key after each letter).. it will alert "duplicate!"
But I also want to figure out how to remove that duplicate from the textarea?
http://jsfiddle.net/P3gpp/
This is the part that seems to not be working ::
sort = sort.push(i);
textVal = sort;
return textVal;
Why do it the hard way, it can be done more easily using javascript filter function which is specifically for this kind of operations:
var arr = ["apple", "bannana", "orange", "apple", "orange"];
arr = arr.filter( function( item, index, inputArray ) {
return inputArray.indexOf(item) == index;
});
---------------------
Output: ["apple", "bannana", "orange"]
Based on user2668376 solution, this will return a new array without duplicates.
Array.prototype.removeDuplicates = function () {
return this.filter(function (item, index, self) {
return self.indexOf(item) == index;
});
};
After that you can do:
[1, 3, 3, 7].removeDuplicates();
Result will be; [1, 3, 7].
These are the functions I created/use for removing duplicates:
var removeDuplicatesInPlace = function (arr) {
var i, j, cur, found;
for (i = arr.length - 1; i >= 0; i--) {
cur = arr[i];
found = false;
for (j = i - 1; !found && j >= 0; j--) {
if (cur === arr[j]) {
if (i !== j) {
arr.splice(i, 1);
}
found = true;
}
}
}
return arr;
};
var removeDuplicatesGetCopy = function (arr) {
var ret, len, i, j, cur, found;
ret = [];
len = arr.length;
for (i = 0; i < len; i++) {
cur = arr[i];
found = false;
for (j = 0; !found && (j < len); j++) {
if (cur === arr[j]) {
if (i === j) {
ret.push(cur);
}
found = true;
}
}
}
return ret;
};
So using the first one, this is how your code could look:
function cleanUp() {
var text = document.getElementById("fld"),
textVal = text.value,
array;
textVal = textVal.replace(/\r/g, " ");
array = textVal.split(/\n/g);
text.value = removeDuplicatesInPlace(array).join("\n");
}
DEMO: http://jsfiddle.net/VrcN6/1/
You can use Array.reduce() to remove the duplicates. You need a helper object to keep track of how many times an item has been seen.
function cleanUp()
{
var textBox = document.getElementById("fld"),
array = textBox.value.split(/\r?\n/g),
o = {},
output;
output = array.reduce(function(prev, current) {
var key = '$' + current;
// have we seen this value before?
if (o[key] === void 0) {
prev.push(current);
o[key] = true;
}
return prev;
}, []);
// write back the result
textBox.value = output.join("\n");
}
The output of the reduce() step can be used directly to populate the text area again, without affecting the original sort order.
Demo
You can do this easily with just an object:
function removeDuplicates(text) {
var seen = {};
var result = '';
for (var i = 0; i < text.length; i++) {
var char = text.charAt(i);
if (char in seen) {
continue;
} else {
seen[char] = true;
result += char;
}
}
return result;
}
function cleanUp() {
var elem = document.getElementById("fld");
elem.value = removeDuplicates(elem.value);
}
arr3 = [1, 2, 3, 2, 4, 5];
unique = [];
function findUnique(val)
{
status = '0';
unique.forEach(function(itm){
if(itm==val){
status=1;
}
})
return status;
}
arr3.forEach(function(itm){
rtn = findUnique(itm);
if(rtn==0)
unique.push(itm);
});
console.log(unique); // [1, 2, 3, 4, 5]
I'm looking for something similar to Groovy's every() method, which tests every element of a list if it meets some criteria. If they all meet the criteria, the function returns true. Otherwise, false. I've tried something like this:
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = $.grep(arr, function(ind) {
return this == 1;
}).length == arr.length;
..but its not very clean. I haven't had any luck while searching through the API. Is using grep() the only way to do it?
if it is a plain js array, you have $.grep()
.filter() is for use with jQuery or DOM Elements
Here is a plugin I made that might make it easier:
(function($) {
$.fn.allOnes = function() {
var allVal = true;
this.each(function(ind, item) {
if (item != 1) {
allVal = false;
return allVal;
}
});
return allVal;
};
})(jQuery);
var arr = [1, 1, 0, 1, 1, 1];
console.log($(arr).allOnes());
Fiddle: http://jsfiddle.net/maniator/NctND/
The following plugin is an expansion of the above and lets you search for a specific number: http://jsfiddle.net/maniator/bFNnn/
(function($) {
$.fn.allValue = function(pred) {
var allOnes = true;
this.each(function(ind, item) {
if (item != pred) {
allOnes = false;
return allOnes;
}
});
return allOnes;
};
})(jQuery);
var arr = [1, 1, 1, 1, 1, 1];
console.log($(arr).allValue(1));
here is example of function you can use.
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = arr.check(1);
//this function compares all elements in array and if all meet the criteria it returns true
Array.prototype.chack = function(cond)
{
var ln = 0;
for(i=0; i<this.length; i++)
{
if(bond === this[i])
{
ln++
}
}
if(ln == this.length)
return true;
else
return false;
}
How about just turning your working code into a method on array, to ease its reuse:
Array.prototype.every = function(predicate){
return $.grep(this,predicate).length == this.length;
}
usage:
alert([1,0,1,0].every(function(i) { return i == 1; }));
Working example: http://jsfiddle.net/59J5A/
Edit: changed to grep
You could always implement an allOnes method:
function allOnes(array) {
var result = [];
for(var i = 0; i < array.length; i += 1) {
if (array[i] === 1) { result.push(true); }
}
return array.length == result.length;
}
or you could be a bit more abstract and test for true/false:
function all(array) {
var result = [];
for(var i = 0; i < array.length; i += 1) {
if (array[i]) { result.push(true); }
}
return array.length == result.length;
}
var arr = [1, 0, 1, 0, 1, 1];
var allOnes = all(arr);
or even better, maybe have a changeable predicate:
function all(array, predicate) {
var result = [],
predicate = predicate || function(x) { if (x) { return true; } };
for(var i = 0; i < array.length; i += 1) {
if (predicate(array[i])) { result.push(true); }
}
return array.length == result.length;
}
var allOnes = all(arr, function(x) { return x === 1; })
how to find duplicates in an array and remove them using javascript?
To do this generically, you could use something like the following, which removes duplicates from the array in place. If you have an array that contains only strings or numbers, you could simplify this significantly.
var arrayContains = Array.prototype.indexOf ?
function(arr, val) {
return arr.indexOf(val) > -1;
} :
function(arr, val) {
var i = arr.length;
while (i--) {
if (arr[i] === val) {
return true;
}
}
return false;
}
function removeDuplicates(arr, equals) {
var val, originalArr = arr.slice(0);
arr.length = 0;
for (var i = 0, len = originalArr.length; i < len; ++i) {
val = originalArr[i];
if (!arrayContains(arr, val)) {
arr.push(val);
}
}
return arr;
}
var arr = [1, 2, 2, 1, 3];
removeDuplicates(arr);
console.log(arr); // [1, 2, 3]
var sampleArr=new Array(1,1,1,1,1,2,2,3,3,3,4,4,4); //Declare array
document.write(uniqueArr(sampleArr)); //Print the unique value
//Adds new uniqueArr values to temp array
function uniqueArr(a) {
temp = new Array();
for(i=0;i<a.length;i++){
if(!contains(temp, a[i])){
temp.length+=1;
temp[temp.length-1]=a[i];
}
}
return temp;
}
//Will check for the Uniqueness
function contains(a, e) {
for(j=0;j<a.length;j++)if(a[j]==e)return true;
return false;
}
for(var i=0; i < arr.length; i++)
{
for(var j=i+1; j < arr.length; j++)
{
if(arr[j] == arr[i])
{
arr.splice(j, 1);
}
}
}