Christian Heilmann

Simulating array_unique in JavaScript

Wednesday, August 8th, 2007 at 2:09 pm

One of the beautiful things of PHP is its wealth of array methods. JavaScript in comparison seems ridiculously inadequate and you find yourself having to write own methods or patch the existing ones. One method I especially cherish is array_unique() which returns a new array that has all the duplicates filtered out. This is easy to write in JavaScript, all you need to do is:

  • create a new object
  • loop through the array and use the array values as new properties of the object (that way the property simply gets re-set and not added as a new one to the object when it comes up again)
  • loop through the properties of the object and add each value to the results array

Technically this should do it:

function array_unique(ar){
var sorter = {};
for(var i=0,j=ar.length;i sorter[ar[i]] = ar[i];
}

ar = [];
for(var i in sorter){
ar.push(i);
}

return ar;
}

Now array_unique([1,2,3,1,1]) returns “[1,2,3]” which is what we want. However, there is a snag. What if the array contains elements that are almost the same but a different type? When you run array_unique([1,2,3,”1”,1]) you still only get “[1,2,3]” as the returned array and what you’d really need is “[1,2,3,’1’]”. The solution to this is to store both the value and the type in the property and push the values to the results array:

function array_unique(ar){
var sorter = {};
for(var i=0,j=ar.length;i sorter[ar[i]+typeof ar[i]] = ar[i];
}

ar = [];
for(var i in sorter){
ar.push(sorter[i]);
}

return ar;
}

The next thing I can think of is to ensure that the array is really an array. We can test this by checking if it has a length property and is not a string.

function array_unique(ar){
if(ar.length && typeof ar!==’string’){
var sorter = {};
for(var i=0,j=ar.length;i sorter[ar[i]+typeof ar[i]] = ar[i];
}

ar = [];
for(var i in sorter){
ar.push(sorter[i]);
}

}
return ar;
}

However, two loops can be slow, and for…in is a very slow construct. Therefore we can avoid the second loop by using an output array:

function array_unique(ar){
if(ar.length && typeof ar!==’string’){
var sorter = {};
var out = [];
for(var i=0,j=ar.length;i if(!sorter[ar[i]+typeof ar[i]]){
out.push(ar[i]);
sorter[ar[i]+typeof ar[i]]=true;
}

}
}

return out || ar;
}

Anything I have forgotten?

Share on Mastodon (needs instance)

Share on BlueSky

Newsletter

Check out the Dev Digest Newsletter I write every week for WeAreDevelopers. Latest issues:

160: Graphs and RAGs explained and VS Code extension hacks Graphs and RAG explained, how AI is reshaping UI and work, how to efficiently use Cursor, VS Code extensions security issues.
159: AI pipelines, 10x faster TypeScript, How to interview How to use LLMs to help you write code and how much electricity does that use? Is your API secure? 10x faster TypeScript thanks to Go!
158: 🕹️ Super Mario AI 🔑 API keys in LLMs 🤙🏾 Vibe Coding Why is AI playing Super Mario? How is hallucinating the least of our worries and what are rules for developing Safety Critical Code?
157: CUDA in Python, Gemini Code Assist and back-dooring LLMs We met with a CUDA expert from NVIDIA about the future of hardware, we look at how AI fails and how to play pong on 140 browser tabs.
156: Enterprise dead, all about Bluesky and React moves on! Learn about Bluesky as a platform, how to build a React App and how to speed up SQL. And play an impossible game in the browser.

My other work: