Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to delete duplicate objects in an array

Status
Not open for further replies.

ttomasko

Programmer
Aug 6, 2008
28
I have an array of objects, some of which are duplicates. I need to pare this down so that there are only unique objects.

I can't show these objects here because they are in the InDesign object model. The best I can do is to make an array of arrays, two of which have equal last elements.

The script here does not work. It returns an array of all the elements of all the arrays. Can someone point me in a direction that will solve this?

Thanks,
Tom

Code:
var a = [[1,2,3],[4,5,6],[7,8,3],[7,8,9]];
var b = new Array;
for(var x = 0; x<a.length; x++){
	for(var y = 0; y<a.length; y++){
		if(a[x][2] != a[y][2]){
			b = b.concat(a[y]);
			}//end if
		}//end for y
	}//end for x
b;
//what I want:  b = [[1,2,3],[4,5,6],[7,8,9]];
 
I think your logic is reversed... instead of assuming an item is unique if it doesn't match a single item should be flipped to say it is a duplicate if it matches any item.

So, you need to either continue your outer loop when you find a dup, or keep a flag. Many JS developers hate the label syntax for continuing outer loops as it's too much like a 'goto'. Personally I have no issue with it, but will show the flag example as well in case you're also in the non-label camp :)

Code:
// Using a label-based continue statement
var a = [[1,2,3],[4,5,6],[7,8,3],[7,8,9]];
var b = [];

outer:
for (var x=0; x<a.length; x++){
    for (var y=0; y<b.length; y++){
        if (b[y][2] == a[x][2]) continue outer;
    }
    // At this point, we've found no match, so assume unique
    b[b.length] = a[x];
}

// Using a flag
var a = [[1,2,3],[4,5,6],[7,8,3],[7,8,9]];
var b = [];

for (var x=0; x<a.length; x++){
    var isDup = false;
    for (var y=0; y<b.length; y++){
        if (b[y][2] == a[x][2]) {
            isDup = true;
            break;
        }
    }
    if (!isDup) b[b.length] = a[x];
}

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Thanks Dan,

Both of these work. Now I have to see if they will work on an array of objects.

I have no problem with labels. What's so wrong with "goto"?

Tom
 
I think that the label syntax is fine... but some developers don't like it for some reason. I guess they think it can lead to unstructured code if over-used.




Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Dan,
I used the flagged code with the InDesign Object Model and it works perfectly! Thanks again.

But I really don't understand the logic of it.

Var b starts out empty. Therefore it's length is zero. So can "y<b.length" if both y and b are zero? I understand that after one iteration b has an element but how does one get there?

Any light on how this works would educate me and I hope a few other people.

On another point, I also need to sort this array--by the last element of each of the sub arrays. I figured out how to do that (and I've never understood how the a-b sort does work):

Code:
function sort2(a,b){
	return a[2]-b[2]
	}//end sort 2
b.sort(sort2);
 
Funny you should ask - the first example I created (which I didn't post) looped around "a" twice instead of "a" once and "b" once.

Given you want to store unique objects (or the first of any non-unique object), the definitive place to check would be that list of unique objects (in this case, "b"). So, for each item in "a" the code checks to see if a dup exists in "b".

Initially, "b" is empty, so no inner loop is executed, and the first item in "a" is placed directly into "b".

From then on, it's a case of checking each item in "a" against "b" to see if a dup exists in "b", and if not, add the item.

As for the sorting, an array method's sort function should return either a negative number (a<b), 0 (a==b), or a positive number (a>b) to determine the sort order - which your subtraction does rather nicely in one line.

Hope this helps,
Dan



Coedit Limited - Delivering standards compliant, accessible web solutions

Dan's Page [blue]@[/blue] Code Couch:
Code Couch Tech Snippets & Info:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top