For example: [8,2,2,5] => [8,2,5]
- The array is not sorted.
- Repeating items always go in a row.
I came up with a solution with two cycles and a second array. So I decided to ask if there is any more elegant solution.
For example: [8,2,2,5] => [8,2,5]
I came up with a solution with two cycles and a second array. So I decided to ask if there is any more elegant solution.
Algorithm with linear asymptotics.
In this implementation, modifies the original array, but can be easily converted to create a new one.
function doSmth(a) { for (var q=1, i=1; q<a.length; ++q) { if (a[q] !== a[q-1]) { a[i++] = a[q]; } } a.length = i; return a; } .length can be installed. Concise and effective! - Sergiksq (reads) and i (writes). When a series of repetitive values begins, q goes forward. And i writes down one new value, trailing behind. As a result, everything to the left of i is unique values one by one. Setting .length = i truncates the array so that only elements to the left of i remain. - Sergiks++q in a loop? - user208916++q or q++ . - Sergiks 5:52 pmThe short solution is:
uniqueArray = a.filter(function(item, pos) { return a.indexOf(item) == pos; }) A little smarter can be this:
function uniq(a) { var seen = {}; return a.filter(function(item) { return seen.hasOwnProperty(item) ? false : (seen[item] = true); }); } Combining these two approaches:
function uniq(a) { var prims = {"boolean":{}, "number":{}, "string":{}}, objs = []; return a.filter(function(item) { var type = typeof item; if(type in prims) return prims[type].hasOwnProperty(item) ? false : (prims[type][item] = true); else return objs.indexOf(item) >= 0 ? false : objs.push(item); }); } The fastest solution (without function calls):
function uniq_fast(a) { var seen = {}; var out = []; var len = a.length; var j = 0; for(var i = 0; i < len; i++) { var item = a[i]; if(seen[item] !== 1) { seen[item] = 1; out[j++] = item; } } return out; } Source with all the details: https://stackoverflow.com/a/9229821/2707359
Option using Set from ECMA2015 and Array.from
var arr = [1,8,2,2,5,5,5,5,7]; document.write(JSON.stringify(arr),'<br/>'); var uniq = Array.from(new Set(arr)); document.write(JSON.stringify(uniq)); Set does the order of the elements save? - Qwertiy ♦Given that repeats are in a row, you can change the source without an additional array: go through the elements, remembering the previous one, and deleting the repeats tails:
var a = [8,2,2,5] ,i = 0 ,pValue // предыдущее значение ,pStart // первая позиция пред. зн. ,cValue // текущее значение ,length = 0 // длина фрагмента с повторами ; while( i++ < a.length) { cValue = a[i]; if( pValue === cValue) { length++; continue; } if(length) { a.splice(pStart,length); i -= length; } pValue = cValue; pStart = i; length = 0; } if(length) a.splice(pStart,length); document.body.innerText = JSON.stringify(a); Solution for your case (all the same elements are next):
uniqArray = a.filter( (item, pos, arr) => !pos || item !== arr[pos - 1] ); Although I would just take a ready-made solution https://lodash.com/docs#sortedUniq
Source: https://ru.stackoverflow.com/questions/539941/
All Articles