jQuery.unique lets you get unique elements of an array, but the docs say the function is mostly for internal use and only operates on DOM elements. Another SO response said the unique() function worked on numbers, but that this use case is not necessarily future proof because it's not explicitly stated in the docs.
Given this, is there a "standard" jQuery function for accessing only the unique values — specifically, primitives like integers — in an array? (Obviously, we can construct a loop with the each() function, but we are new to jQuery and would like to know if there is a dedicated jQuery function for this.)
You can use array.filter to return the first item of each distinct value-
var a = [ 1, 5, 1, 6, 4, 5, 2, 5, 4, 3, 1, 2, 6, 6, 3, 3, 2, 4 ];
var unique = a.filter(function(itm, i, a) {
return i == a.indexOf(itm);
});
console.log(unique);
If supporting IE8 and below is primary, don't use the unsupported filter method.
Otherwise,
if (!Array.prototype.filter) {
Array.prototype.filter = function(fun, scope) {
var T = this, A = [], i = 0, itm, L = T.length;
if (typeof fun == 'function') {
while(i < L) {
if (i in T) {
itm = T[i];
if (fun.call(scope, itm, i, T)) A[A.length] = itm;
}
++i;
}
}
return A;
}
}
Just use this code as the basis of a simple JQuery plugin.
$.extend({
distinct : function(anArray) {
var result = [];
$.each(anArray, function(i,v){
if ($.inArray(v, result) == -1) result.push(v);
});
return result;
}
});
Use as so:
$.distinct([0,1,2,2,3]);
Based on #kennebec's answer, but fixed for IE8 and below by using jQuery wrappers around the array to provide missing Array functions filter and indexOf:
$.makeArray() wrapper might not be absolutely needed, but you'll get odd results if you omit this wrapper and JSON.stringify the result otherwise.
var a = [1,5,1,6,4,5,2,5,4,3,1,2,6,6,3,3,2,4];
// note: jQuery's filter params are opposite of javascript's native implementation :(
var unique = $.makeArray($(a).filter(function(i,itm){
// note: 'index', not 'indexOf'
return i == $(a).index(itm);
}));
// unique: [1, 5, 6, 4, 2, 3]
I would use underscore.js, which provides a uniq method that does what you want.
// for numbers
a = [1,3,2,4,5,6,7,8, 1,1,4,5,6]
$.unique(a)
[7, 6, 1, 8, 3, 2, 5, 4]
// for string
a = ["a", "a", "b"]
$.unique(a)
["b", "a"]
And for dom elements there is no example is needed here I guess because you already know that!
Here is the jsfiddle link of live example:
http://jsfiddle.net/3BtMc/4/
Paul Irish has a "Duck Punching" method (see example 2) that modifies jQuery's $.unique() method to return unique elements of any type:
(function($){
var _old = $.unique;
$.unique = function(arr){
// do the default behavior only if we got an array of elements
if (!!arr[0].nodeType){
return _old.apply(this,arguments);
} else {
// reduce the array to contain no dupes via grep/inArray
return $.grep(arr,function(v,k){
return $.inArray(v,arr) === k;
});
}
};
})(jQuery);
Walk the array and push items into a hash as you come across them. Cross-reference the hash for each new element.
Note that this will ONLY work properly for primitives (strings, numbers, null, undefined, NaN) and a few objects that serialize to the same thing (functions, strings, dates, possibly arrays depending on content). Hashes in this will collide as they all serialize to the same thing, e.g. "[object Object]"
Array.prototype.distinct = function(){
var map = {}, out = [];
for(var i=0, l=this.length; i<l; i++){
if(map[this[i]]){ continue; }
out.push(this[i]);
map[this[i]] = 1;
}
return out;
}
There's also no reason you can't use jQuery.unique. The only thing I don't like about it is that it destroys the ordering of your array. Here's the exact code for it if you're interested:
Sizzle.uniqueSort = function(results){
if ( sortOrder ) {
hasDuplicate = baseHasDuplicate;
results.sort(sortOrder);
if ( hasDuplicate ) {
for ( var i = 1; i < results.length; i++ ) {
if ( results[i] === results[i-1] ) {
results.splice(i--, 1);
}
}
}
}
return results;
};
this is js1568's solution, modified to work on a generic array of objects, like:
var genericObject=[
{genProp:'this is a string',randomInt:10,isBoolean:false},
{genProp:'this is another string',randomInt:20,isBoolean:false},
{genProp:'this is a string',randomInt:10,isBoolean:true},
{genProp:'this is another string',randomInt:30,isBoolean:false},
{genProp:'this is a string',randomInt:40,isBoolean:true},
{genProp:'i like strings',randomInt:60,isBoolean:true},
{genProp:'this is a string',randomInt:70,isBoolean:true},
{genProp:'this string is unique',randomInt:50,isBoolean:true},
{genProp:'this is a string',randomInt:50,isBoolean:false},
{genProp:'i like strings',randomInt:70,isBoolean:false}
]
It accepts one more parameter called propertyName, guess! :)
$.extend({
distinctObj:function(obj,propertyName) {
var result = [];
$.each(obj,function(i,v){
var prop=eval("v."+propertyName);
if ($.inArray(prop, result) == -1) result.push(prop);
});
return result;
}
});
so, if you need to extract a list of unique values for a given property, for example the values used for randomInt property, use this:
$.distinctObj(genericObject,'genProp');
it returns an array like this:
["this is a string", "this is another string", "i like strings", "this string is unique"]
function array_unique(array) {
var unique = [];
for ( var i = 0 ; i < array.length ; ++i ) {
if ( unique.indexOf(array[i]) == -1 )
unique.push(array[i]);
}
return unique;
}
Plain JavaScript modern solution if you don't need IE support (Array.from is not supported in IE).
You can use combination of Set and Array.from.
const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];
const set = new Set(arr);
const uniqueArr = Array.from(set);
console.log(uniqueArr);
The Set object lets you store unique values of any type, whether primitive values or object references.
The Array.from() method creates a new Array instance from an array-like or iterable object.
Also Array.from() can be replaced with spread operator.
const arr = [1, 1, 11, 2, 4, 2, 5, 3, 1];
const set = new Set(arr);
const uniqueArr = [...set];
console.log(uniqueArr);
You can use a jQuery plugin called Array Utilities to get an array of unique items.
It can be done like this:
var distinctArray = $.distinct([1, 2, 2, 3])
distinctArray = [1,2,3]
If anyone is using knockoutjs try:
ko.utils.arrayGetDistinctValues()
BTW have look at all ko.utils.array* utilities.
As of jquery 3.0 you can use $.uniqueSort(ARRAY)
Example
array = ["1","2","1","2"]
$.uniqueSort(array)
=> ["1", "2"]
If you need to support IE 8 or earlier, you can use jQuery to accomplish this.
var a = [1,2,2,3,4,3,5];
var unique = $.grep(a, function (item, index) {
return index === $.inArray(item, a);
});
Related
I want to extend the Array with a new method called square() which returns a new array with all the numbers squared. I tried making it but I can't figure out a way in which the function does not take any parameters like the default JS Array methods. For example array.reverse() returns the array reversed it doesn't take the array as the parameter, like this: array.reverse(array)
This is my code:
Array.prototype.square = function(Array){
let a = []
for (let num of Array){
a.push(num**2)
}
return a
}
You can use the this keyword inside of your function and it will refer to the array calling it.
Array.prototype.square = function() {
return this.map(number => number ** 2)
}
let test = [1, 2, 3]
console.log(test.square())
You were on the right track, it can be easily done like this:
Array.prototype.square = function () {
return this.map((number) => number * number)
}
let a = [1, 2]; // sample array
console.log(a.square()); // prints [1, 4]
I have used map, which makes the process extremely easy. Refer to this for more information: Array Map Function
for the record...
(the name of this kind of added method is called a wrapper)
/* --- Array.square wrapper--- */
if (!Array.prototype.square) // check that the square method does not already exist
{
Array.prototype.square = function(){ return this.map(x=>x**2) }
}
let arr1 = [1,2,3,5,7]
, arr2 = arr1.square()
;
console.log('arr1 ->', JSON.stringify( arr1 ))
console.log('arr2 ->', JSON.stringify( arr2 ))
When you add methods to a prototype the object/array will always be the this context. So you can simply loop over this.
(Aside: it's often good to check that the method doesn't already exist on the prototype which is why I included that code too.)
if (!('square' in Array.prototype)) {
Array.prototype.square = function() {
const arr = [];
for (let i = 0; i < this.length; i++) {
arr.push(this[i] ** 2);
}
return arr;
}
}
console.log([1, 2, 3].square());
Or, more simply, use map to return a new array.
if (!('square' in Array.prototype)) {
Array.prototype.square = function() {
return this.map(el => el ** 2);
}
}
console.log([1, 2, 3].square());
Is there a way to loop backwards through an array using forEach (not any other kind of loop, I know how to do with with a for / standard ways) and without actually reversing the array itself?
let arr = [1, 2, 3];
arr.slice().reverse().forEach(x => console.log(x))
will print:
3
2
1
arr will still be [1, 2, 3], the .slice() creates a shallow copy.
There is a similar array method that has a reverse counter part, reduce comes together with reduceRight:
const array = ['alpha', 'beta', 'gamma'];
array.reduceRight((_, elem) => console.log(elem), null);
When using it for the requested purpose, make sure to provide a second argument. It can be null or anything else. Also note that the callback function has as first argument the accumulator, which you don't need for this purpose.
If including a library is an option:
Lodash: forEachRight.
Just use a for loop. Start at the end of the array and go backwards from there.
const array = ['blastoff', 1, 2, 3];
for (let index = array.length - 1; index >= 0; index--) {
const element = array[index];
console.log(element);
}
No, forEach only processes forward through the array. So you'd have to do something else, which you've said in your question was out of scope.
I can think of two options which just use precursors to using forEach (so, they don't use a for loop or other kind of loop). I don't know if those would be out of scope or not, so here they are:
Copy the array and reverse the copy, then use forEach on it
Use Object.keys to get the indexes, reverse that, then use forEach on it (which will loop through the indexes, not the values, but then we can look them up)
Here's #1:
slice copies the array (shallow copy, so not likely to be expensive), then we reverse it, then forEach:
var a = ['one', 'two', 'three'];
a.slice().reverse().forEach(function(entry) {
console.log(entry);
});
console.log("Proof that a is not, itself, reversed: " +
JSON.stringify(a));
Here's #2:
We use Object.keys to get the array indices (using filter if you store non-element properties in your arrays), reverse that, and then loop through the result:
var a = ['one', 'two', 'three'];
Object.keys(a).reverse().forEach(function(index) {
console.log(a[index]);
});
console.log("Proof that a is not, itself, reversed: " +
JSON.stringify(a));
Side note: Here's what I mean about using filter if you have non-element properties on your array:
var a = ['one', 'two', 'three'];
a.nonElementProperty = "foo";
Object.keys(a).filter(function(name) {
return String(+name) === name;
}).reverse().forEach(function(index) {
console.log(a[index]);
});
console.log("Proof that a is not, itself, reversed: " +
JSON.stringify(a));
As yet the browsers do not seem to have optimised the Array.forEach function. With not much effort you can write a simple polyfill that out performs the Array.forEach method by at least 10 to 1.
So you can create your own Array.revEach and have it outperform the native Array.forEach, thought I hope that the browsers address the very slow performance of Array.forEach soon and make the need to polyfill actual existing methods not necessary.
For Array.revEach out performs Array.forEach running 17 times faster on "Chrome 46.0.2490.22 beta-m"
if (Array.prototype.revEach === undefined) {
Object.defineProperty(Array.prototype, 'revEach', {
writable : false,
enumerable : false,
configurable : false,
value : function (func) {
var i;
var len = this.length-1;
for (i = len; i >= 0; i--) {
func(this[i], i, this);
}
}
});
}
Just to add the actual official polyfill modified to reverse. Comments show my changes.
// Production steps of ECMA-262, Edition 5, 15.4.4.18
// Reference: http://es5.github.io/#x15.4.4.18
// Modified by Blindman67 to revEach
if (!Array.prototype.revEach) { // name changed
Array.prototype.revEach = function(callback, thisArg) { // name changed
var T; // k defined where len was
if (this == null) {
throw new TypeError(' this is null or not defined');
}
var O = Object(this);
var k = (O.length >>> 0)-1; // set k (counter) ToUint32
// len var removed
if (typeof callback !== "function") {
throw new TypeError(callback + ' is not a function');
}
if (arguments.length > 1) {
T = thisArg;
}
while (k >= 0) { // reverse condition
var kValue;
if (k in O) {
kValue = O[k];
callback.call(T, kValue, k, O);
}
k--; // dec counter
}
};
}
array.forEach has 3 parameters. You can use these to effectively forEach backward.
var arr = [1, 2, 3];
arr.forEach(function(x, index, the_array) {
let x_prime = the_array[the_array.length-1-index]
console.log(x_prime);
})
will print
3
2
1
This can be accomplished relatively concisely using the reverse method, the forEach method, and (if using ES6) the arrow function
var someArray = ["a","b","c","d"];
someArray.reverse().forEach(arrayItem =>
console.log(arrayItem)
)
If you are not using ES6, the solution is about the same, just without the arrow function.
var someArray = ["a","b","c","d"];
someArray.reverse().forEach(function(arrayItem) {
console.log(arrayItem)
})
Both will print to the console:
d
c
b
a
There are many ways to achive this task.
Firsly we can use Array.reduceRight() method
[1,2,3,4,5].reduceRight((total,item) => {
console.log(item);
// Do somthing here and remember the return statement
return item;
},0)
Output: 5,4,3,2,1
the reduceRight method traverse an array in right to left manner and we can get advantage of it.
,but always keep in mind that you have to return something to keep going this loop until the length is reached.
As a second method we can use Array.reverse()
this method first format the array in reversed manner then returns it, and now you can iterate in reverse manner.
[1,2,3].reverse().map(n => console.log(n));
Output: 3,2,1
But the disadvantage of this method is that if you have thousands of entries in array then it may affect your performance.
Third and the most easiest way it to use classical for loop
let array = [1,2,3,4,5];
let start = array.length;
for(;start >= 0;start--){
// travese in right to left manner
console.log(array[start])
}
What about:
const array = [1, 2, 3];
const revArray = [...array].reverse() // won't affect the original array
revArray.forEach(x => console.log(x)) // 3, 2, 1
One liner:
[...array].reverse().forEach(x => console.log(x)) // 3, 2, 1
With index var:
[...array].reverse().forEach((val, index) => {
const revIndex = array.length - i - 1
console.log(revIndex) // 0, 1, 2
console.log(revIndex) // 2, 1, 0
console.log(val) // 3, 2, 1
})
You can also do it this way
let arr = [1, 3, 5, 7, 9];
arr.forEach(value => {
console.log(value);
})
let reversed = new Array(arr.reverse());
console.log("\n\nReversed: ");
reversed.forEach(value => {
value.forEach(val => {
console.log(val)
})
})
I am a javascript beginner trying to solve a challenge posed by an online code camp. This problem is similar to that posed at Using an array to filter an array Javascript. I have studied this but remain unsuccessful. I have tried for many hours without arriving at a solution.
The exact challenge states:
Remove all values (last argument(s)) from an array (first argument) and >return as a new array.
I know this is not much to go on. In the example below, the desired output would be the following array:
[1,1]
The basic premise is to filter the first argument, which is an array, by x number of non-array arguments. Where the array elements are the same as the non-array arguments, those elements would be removed from the array. Below is a non-functioning sample of a path I've attempted:
<code>
function result(arr) {
var list = [];
var i;
for(i in Object.keys(arguments)) {
if(i > 0) {
list.push(arguments[i]);
}
}
function answer(arr1, arr2) {
return arr1.filter(function(a) {
return arr2.indexOf(a) >= 0;
});
}
return answer(arr, list);
}
result([1, 2, 3, 1, 2, 3], 2, 3);
</code>
OK, now maybe I understand. If that's the actual challenge wording, it is poorly worded.
My interpretation is that you are being asked to write a function that takes a first argument that is an array and then after that zero or more successive arguments. The task is to remove all the zero or more successive arguments from the array that was passed in and return a new array with those items removed.
function filterArray(sourceArray, arg1, arg2 /* ... more args */) {
// get arguments after the first argument into their own array
var args = Array.prototype.slice.call(arguments, 1);
return sourceArray.filter(function(element, index, array) {
return args.indexOf(element) === -1;
});
}
This works by getting the successive arguments into their own array and then calling .filter() on the sourceArray. The callback for .filter() then uses .indexOf() to check if each element is in the argument list. If it is not, return true to keep the value in the output array. If it is in the argument list, return false so it is removed from the output array.
Working demo: http://jsfiddle.net/jfriend00/u8c5vvd9/
If you want compatibility with versions of IE before IE9, you can either add a polyfill for .filter() and .indexOf() which is easy and shown here and here or you could do the filtering manually like this:
function filterArray(sourceArray, arg1, arg2 /* ... more args */) {
var result = [], found, item;
for (var i = 0; i < sourceArray.length; i++) {
item = sourceArray[i];
found = false;
for (var argIndex = 1; argIndex < arguments.length; argIndex++) {
if (arguments[argIndex] === item) {
found = true;
break;
}
}
if (!found) {
result.push(item);
}
}
return result;
}
Working demo: http://jsfiddle.net/jfriend00/g586cbpp/
This will check for an exact match of all arguments against the values in the input array. And then return an array stripped of those values.
It does not use .filter() .slice() .call() or Object.keys() so it is fully compliant with ancient web-browser versions.
<script type="text/javascript">
function result(input_array) {
// Breakpoint if input is not an array... return the object inside an array for consistency of return type
if( !(input_array instanceof Array) ) return [].push(input_array);
// Gather list of arguments to reject.
var reject_list = [];
for(var i in arguments)
if(i > 0)
reject_list.push(arguments[i]);
// check each element in the input array if it is a value to reject.
var output_array = []
for(var i = 0; i < input_array.length; i++){
var value_is_ok = true
for(var r = 0; r < reject_list.length; r++){
if( input_array[i] == reject_list[r] ){
value_is_ok = false
break
}//endif
}//endfor
if( value_is_ok )
output_array.push(input_array[i]);
}//endfor
return output_array
}
var my_array = [1, 2, 3, 1, 2, 3]
console.log( result(my_array, 2, 3) ) // result is [1,1]
</script>
The easiest solution I can imagine would be:
function result(haystack) {
// converting the 'non-array' list of additional arguments
// into an array:
var needles = Array.prototype.slice.call(arguments, 1),
// using Array.prototype.filter() to filter the
// supplied array ('haystack'):
filtered = haystack.filter(function (el) {
// the first argument ('el') is the current array-element
// if the current array-element is *not* found in the
// array of 'needles', we retain the element:
return needles.indexOf(el) === -1;
});
return filtered;
}
console.log(result([1, 2, 3, 1, 2, 3], 2, 3)); // [1, 1]
This solution, particularly the use of Array.prototype.filter(), is problematic in IE 8, the MDN reference link (below) offers a shim for those older browsers.
function result(haystack) {
var needles = Array.prototype.slice.call(arguments, 1),
filtered = haystack.filter(function(el) {
return needles.indexOf(el) === -1;
});
/* just to display the values: */
document.getElementById('haystack').textContent = haystack.join(', ');
document.getElementById('needles').textContent = needles.join(', ');
document.getElementById('result').textContent = filtered.join(', ');
return filtered;
}
console.log(result([1, 2, 3, 1, 2, 3], 2, 3));
ol, li {
list-style-type: none;
}
li::before {
content: attr(id) ': ';
display: inline-block;
width: 20%;
text-transform: capitalize;
}
li:empty {
display: none;
}
<ol>
<li id="haystack"></li>
<li id="needles"></li>
<li id="result"></li>
</ol>
References:
Array.prototype.filter().
Array.prototype.slice().
Function.prototype.call().
I have this array, var arr = [0, 1, 2]
and I would like to convert it into an object like this,
Object{
data: [0, 1, 2]
}
How would I get the desired output using a function perhaps? Thanks.
Just create an object and assign the array to one it it's properties:
var arr = [0, 1, 2];
var obj = {
data : arr
};
Or if you have an existing object, you can add the array by name:
obj['data'] = arr;
Or dot notation:
obj.data = arr;
You should be aware that these are all copying the array by reference, so any updates you make to the arr variable will update obj.data as well. If you want to copy by value, you could do something like:
var obj = {
data: arr.slice(0)
};
See this JSFiddle for an example of copying by reference versus copying by value. You could read the answer to this question for more information about copying by value vs copying by reference.
You can do this very easily like this var obj = {data:arr}; However I think you should consider what purpose you are using the object for. An array is technically already a javascript object so you may not even need to do this
It's quite easy you just need a factory for it.
function arrayToObjectTransformationFactory($array, $transformationTransportProtocol){
return function($array){
if ( !Array.prototype.forEach ) {
Array.prototype.forEach = function(fn, scope) {
for(var i = 0, len = this.length; i < len; ++i) {
fn.call(scope, this[i], i, this);
}
};
}
$array.forEach($transformationTransportProtocol)
return { "data": $array };
}($array);
}
arrayToObjectTransformationFactory([0, 1, 2], function($element, $index, $array){
var quux = [];
quux.push($array[$index]);
});
Should work cross browser and with jQuery too.
This question already has answers here:
Get all unique values in a JavaScript array (remove duplicates)
(91 answers)
Closed 1 year ago.
In my CouchDB reduce function I need to reduce a list of items to the unique ones.
Note: In that case it's ok to have a list, it will be a small number of items of string type.
My current way is to set keys of a object, then return the keys of that object
since the place the code can't use things like _.uniq for example.
I'd like to find a more elegant way to spell it than this.
function(keys, values, rereduce) {
// values is a Array of Arrays
values = Array.concat.apply(null, values);
var uniq = {};
values.forEach(function(item) { uniq[item] = true; });
return Object.keys(uniq);
}
The best method seem to be using ES6 and Set. Single line and faster* than above according to fiddle
const myList = [1,4,5,1,2,4,5,6,7];
const unique = [...new Set(myList)];
console.log(unique);
*tested in safari
2021 answer:
const unique = (arr) => [...new Set(arr)];
unique([1, 2, 2, 3, 4, 4, 5, 1]); // [1, 2, 3, 4, 5]
Here you just create a set from the given array and then convert it back to the array.
I measured performance and it's almost twice faster now than the approach proposed in the old answer I posted before. Also, it's just a one-liner.
Updated fiddle
Old answer just for the record:
Commonly, the approach you used is a good idea.
But I could propose a solution that will make the algorithm a lot faster.
function unique(arr) {
var u = {}, a = [];
for(var i = 0, l = arr.length; i < l; ++i){
if(!u.hasOwnProperty(arr[i])) {
a.push(arr[i]);
u[arr[i]] = 1;
}
}
return a;
}
As you can see we have only one loop here.
I've made an example that is testing both your and my solutions. Try to play with it.
An alternative that's suitable for small lists would be to ape the Unix command line approach of sort | uniq:
function unique(a) {
return a.sort().filter(function(value, index, array) {
return (index === 0) || (value !== array[index-1]);
});
}
This function sorts the argument, and then filters the result to omit any items that are equal to their predecessor.
The keys-based approach is fine, and will have better performance characteristics for large numbers of items (O(n) for inserting n items into a hashtable, compared to O(n log n) for sorting the array). However, this is unlikely to be noticeable on small lists. Moreover, with this version you could modify it to use a different sorting or equality function if necessary; with hash keys you're stuck with JavaScripts notion of key equality.
This should work with anything, not just strings:
export const getUniqueList = (a: Array<any>) : Array<any> => {
const set = new Set<any>();
for(let v of a){
set.add(v);
}
return Array.from(set);
};
the above can just be reduced to:
export const getUniqueValues = (a: Array<any>) => {
return Array.from(new Set(a));
};
:)
To get unique objects, you can use JSON.stringify and JSON.parse:
const arr = [{test: "a"}, {test: "a"}];
const unique = Array.from(new Set(arr.map(JSON.stringify))).map(JSON.parse);
console.log(unique);
Using Object.keys will give you strings if you put in integer arguments (uniq([1,2,3]) => ['1','2','3']. Here's one with Array.reduce:
function uniq(list) {
return list.reduce((acc, d) => acc.includes(d) ? acc : acc.concat(d), []);
}
This is an old question, I know. However, it is at the top of some google searches, so I wanted to add that you can combine the answers from #RobHague and #EugeneNaydenov using the following:
function unique(arr) {
const u = {};
return arr.filter((v) => {
return u[v] = !u.hasOwnProperty(v);
});
};
You can also ignore undefined values (often handy) by adding:
function unique(arr) {
const u = {};
return arr.filter((v) => {
return u[v] = (v !== undefined && !u.hasOwnProperty(v));
});
};
You can play with this solution here: https://jsfiddle.net/s8d14v5n/
I find the other answers to be rather complicated for no gain that I can see.
We can use the indexOf method of the Array to verify if an item exists in it before pushing:
const duplicated_values = ['one', 'one', 'one', 'one', 'two', 'three', 'three', 'four'];
const unique_list = [];
duplicated_values.forEach(value => {
if (unique_list.indexOf(value) === -1) {
unique_list.push(value);
}
});
console.log(unique_list);
That will work with any type of variable as well, even objects (given the identifier actually reference the same entity, merely equivalent objects are not seen as the same).
what about
function unique(list) {
for (i = 0; i<list.length; i++) {
for (j=i+1; j<list.length; j++) {
if (list[i] == list[j]) {
list.splice(j, 1);
}
}
}
}