i need an equivalent to PHP's array_unique function

L

lkrubner

The PHP scripting language has the array_unique() function that gets
the unique, non-redundant values out of an array.

Does Javascript have anything similar?
 
J

Jc

The PHP scripting language has the array_unique() function that gets
the unique, non-redundant values out of an array.

Does Javascript have anything similar?

The short answer is no, but there's a few ways around it.

If you use an Object as a pretend associative array you can either
iterate once through the array and put each element into the
associative array and get a unique list (but it won't be guaranteed to
be in the same order as the indexed array, using the for..in
statement). You could also just use an "associative array" to start
with, instead of an array.

If you care about order, you could add the data to both an associative
array and the indexed array, and use the associative array to quickly
check if the data already exists before adding it to the arrays.
 
R

Randy Webb

Jc said:
The short answer is no, but there's a few ways around it.

If you use an Object as a pretend associative array you can either
iterate once through the array and put each element into the
associative array and get a unique list (but it won't be guaranteed to
be in the same order as the indexed array, using the for..in
statement). You could also just use an "associative array" to start
with, instead of an array.

The only problem being that JS has no "associative arrays".
 
J

Jc

Randy said:
The only problem being that JS has no "associative arrays".

I agree that JS does not explicitly implement a data structure called
an "associative array". However, being such an expressive language, JS
objects can definitely be used as a collection of name/value pairs,
which I don't have a problem referring to informally as an associative
array. Not to mention that this is significantly more meaningful to
someone coming from a PHP background.

I thought it was obvious that in my previous post I was referring to a
feature in JS which is commonly referred to as an "associative array"
for simplicity in explanations. Notice how I said "pretend", and notice
I quoted the words "associative arrays", and notice how I said to use a
JS object, which is how JS implements what is known as an associative
array in other languages.

Just to clarify things, when I referred to using a JS object as a
pretend associative array, I was referring to the technique described
on the following site (someone may have a better link):

http://www.unix.org.ua/orelly/web/jscript/ch07_06.html

FYI: An interesting application of JS objects used in this way (in
combination with an initialization syntax/notation) is JSON:

http://www.crockford.com/JSON/index.html
 
S

Stephen Chalmers

The PHP scripting language has the array_unique() function that gets
the unique, non-redundant values out of an array.

Does Javascript have anything similar?

I think these functions will do what you want.

..arrayUnique() returns a new array containing the unique values,

..trashDuplicates() acts upon the original array, returning it with duplicates removed.
For strict type-comparisons, remove the comments in the 'if' statement.

<SCRIPT type='text/javascript'>

var dups=["1", 1, "four", "3", 2, "2", 1, "four", "2", 2, 3, "3",2];

if( typeof Array().arrayUnique=='undefined' )
Array.prototype.arrayUnique=function()
{
var noDuplicates=[];

for( var i=0, k=0; i<this.length; i++ )
{
for( var j=0; j<noDuplicates.length && this!=noDuplicates[j] ; j++ )
;
if(j==noDuplicates.length)
noDuplicates[k++]=this;
}

return noDuplicates;
}


if( typeof Array().trashDuplicates=='undefined' ) // as if...
Array.prototype.trashDuplicates=function()
{
for( var i=0; i<this.length; i++ )
for( var j=0; j<this.length; j++ )
if( i!=j && this==this[j] /** && typeof(this)==typeof(this[j]) **/ )
for( var k=j; k<this.length; k++ )
{
this[k]=this[k+1];
this.length--;
} // no .splice() in I.E. 5.0 :(

return this;
}

alert("dups.arrayUnique()==[ "+dups.arrayUnique() +" ]\n\ndups.trashDuplicates()==["
+dups.trashDuplicates()+"] New length is: "+dups.length);

</SCRIPT>
 
F

fox

The PHP scripting language has the array_unique() function that gets
the unique, non-redundant values out of an array.

Does Javascript have anything similar?

works with indexed, associative, and "mixed" arrays:


Array.prototype.unique = function()
{

var mark = [];

for(var i in this)
{

// var indx = this; --> if type does not matter


// create a unique index if type does matter
var indx = this + "_" + typeof(this);

if(mark[indx])
delete this;
else
mark[indx] = this;
}

this.sort();

// empty indexed entries are at the end of the array
// shorten it [delete does not reduce array]

while(!this[this.length-1]) this.length--;

}


var dups = ["1", 1, "four", "3", "2", 2, 1, "four", "2", 2, 3, "3"];

dups["quick"] = 44;
dups["brown"] = "test";
dups["fox"] = 44;
dups["jumps"] = "test";



dups.unique();

dups is changed -- no need to create a new array to receive a result.

resultant array is sorted (hope that doesn't matter)

result of dups.unique():

slot : value type
0 : 1 --> number
1 : 1 --> string
2 : 2 --> number
3 : 2 --> string
4 : 3 --> number
5 : 3 --> number
6 : four --> string
quick: 44 --> number
brown: test --> string


result if type doesn't matter:

0 : 1
1 : 2
2 : 3
3 : four
quick: 44
brown: test
 
F

fox

*** correction follows ***

Array.prototype.unique = function()
{

var mark = [];

for(var i in this)
{

// var indx = this; --> if type does not matter


// create a unique index if type does matter
var indx = this + "_" + typeof(this);

if(mark[indx])
delete this;
else
mark[indx] = this;
}

this.sort();

// empty indexed entries are at the end of the array
// shorten it [delete does not reduce array]



if(this.length) {
while(!this[this.length-1]) this.length--; }

}
[**IE did not start generating errors until it was restarted]
 
G

Grant Wagner

Jc said:
The short answer is no, but there's a few ways around it.

If you use an Object as a pretend associative array you can either
iterate once through the array and put each element into the
associative array and get a unique list (but it won't be guaranteed to
be in the same order as the indexed array, using the for..in
statement). You could also just use an "associative array" to start
with, instead of an array.

If you care about order, you could add the data to both an associative
array and the indexed array, and use the associative array to quickly
check if the data already exists before adding it to the arrays.

He can implement something that works very similar to PHP's
array_unique() quite easily:

<script type="text/javascript">
// modifies the current Array
function array_unique(arr) {
var existingItems = {};
var prefix = String(Math.random() * 9e9);
var ii = 0;
while (ii < arr.length) {
if (existingItems[prefix + arr[ii]]) {
arr.splice(ii, 1);
} else {
existingItems[prefix + arr[ii]] = true;
++ii;
}
}
}
// returns a copy
function array_unique2(arr) {
var newArray = [];
var existingItems = {};
var prefix = String(Math.random() * 9e9);
for (var ii = 0; ii < arr.length; ++ii) {
if (!existingItems[prefix + arr[ii]]) {
newArray.push(arr[ii]);
existingItems[prefix + arr[ii]] = true;
}
}
return newArray;
}

var a = [ 'one', 'two', 'three', 'two', 'one' ];
alert(array_unique2(a));
array_unique(a);
alert(a);
</script>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top