Link to home
Start Free TrialLog in
Avatar of jmc430
jmc430

asked on

remove duplicate array objects

how do i remove duplicate array objects?

thanks
Avatar of imladris
imladris
Flag of Canada image

The simple brute force tactic is to have (or create) a second array. Then copy elements across, from one array to the other, while checking if they are duplicate. In psuedo code something like:

Array withdup
Array nodup
int len  // length of array
int counter // count if items in nodup array
for all elements of withdup
    get the current value
    for all elements of nodup
         compare value to current element
    if current value not found in nodup array
        counter = counter + 1   // add value to nodup array
        nodup[counter]=current value

Which language?
If your data is organized in an unordered contiguos array, then there is not a "best method" to eliminate duplicates, as imladris said.
Some programming languages like C++ allows you to store your information in more efficient structures like maps and binary trees, that allows you to easily detect and discard duplicates and even avoid to insert a duplicate item in an array.
Also, if your information comes from a database, there is always an option to retrieve data without duplicates.
Avatar of jmc430
jmc430

ASKER

Java ..

i've got two nsarrays .. and i added them together into one nsmutable set.   i thought using addObjectsFromArray would prevent identical objects from being added to the set.  

NSMutableSet ms = new NSMutableSet();
ms.addObjectsFromArray(a);
ms.addObjectsFromArray(b);

how do i remove the identical objects?  i tried minusSet but it didn't work..

The first problem you have to define us what you consider to be 'identical objects'. To you mean strings that are equal. Objects that have the same hash code? Once that is clear, a filter may be devised to get rid of those 'duplicates'. Second, in a mathematical sense a set is just a bunch of stuff, it can be a bunch of the same stuff. So the NSMutableSet implementation is not going to define some form of identity (comparability, countability) derived from the fact that it belongs to this set. Even the order in which you would read out the objects is meaningless. If you DO care about some identity, e.g. from the index of an object in an array, use NSArray.addObjectsFromArray(...) instead. This would still not remove 'identical object', but if you let us know what you mean with 'identical', I am sure the fix for that is easy. BTW, are you developing on a Mac? What are you interfacing with? Cocoa, webobjects, objective-c? Since you are referring to minusSet, I am guessing objective-c?

Second thought: Do you mean with identical 'the same' object? In java that would mean the simple == operator. But then you really should not use NSMutableSet BEFORE you removed duplicates, because trying to do removeObject() on the set would remove ALL references in the set, if that is in fact how the set is implemented (as a bucket of references to objects, which sounds most reasonable). The simplest and most computation-intensive solution is then to loop through array a and see whether each one of its objects is in array b, and if so, remove it in array b. Then add both arrays to the set.
Avatar of jmc430

ASKER

I'm using Webobjects with Java.  I referred to minusSet because I was reading about NSSet terminology..

My "identical objects" are Department objects.  I'm trying to access all the Departments a Person is affiliated with, as a Department Member and also as a Department Administrator.  There are two arrays connecting a Person to a Department: "deptAdmins" and "affiliations".  My identical objects are the NSArrays that compose the these Person relationships to Department, "Affiliations_Department" and "DeptAdmins_Department".   These are Department  objects, connected through two different relationships, but Department objects nonetheless.

My function is to getAllDepartments is as follows:

public NSArray getAllDepartments() {
     NSArray a = (NSArray)storedValueForKey("affiliations_department");
     NSArray b = (NSArray)storedValueForKey("deptAdmins_department");
     
       if (a == null && b ==null)
        return NSArray.EmptyArray;
       
        NSMutableSet ms = new NSMutableSet();
        ms.addObjectsFromArray(a);
        ms.addObjectsFromArray(b);
        NSArray originalListWithDuplicates = ms.allObjects();
        NSSet uniqueingSet=new NSSet(originalListWithDuplicates);
        NSArray newListWithoutDuplicates=uniqueingSet.allObjects();
     
        EOSortOrdering ordering1 = new EOSortOrdering("departmentName", EOSortOrdering.CompareAscending);
        NSMutableArray sortOrdering = new NSMutableArray();
        sortOrdering.addObject(ordering1);
        return EOSortOrdering.sortedArrayUsingKeyOrderArray(newListWithoutDuplicates, sortOrdering);
     
    }

How would I implement the loop through array and remove it from array b?  

Am I completely off the mark on my implementation?

Thanks for all your help!
jamie
Not completely off the mark. I don't think the following lines from your code will actually remove 'duplicates':

NSArray originalListWithDuplicates = ms.allObjects();
NSSet uniqueingSet=new NSSet(originalListWithDuplicates);
NSArray newListWithoutDuplicates=uniqueingSet.allObjects();

You still have not answered my question to what makes two objects in your set identical, but from your description I am assuming that you want unique Department objects. So one department object would then be 'identical' to another one if both have the same departmentName. It would be better to use some form of key or id, if you have it available, e.g. maybe  departId.

After

if (a == null && b ==null)
        return NSArray.EmptyArray;

Try something like this (this semi-pseude-code is not checked for syntax errors, I am assuming the class name for your departments is Department)

Department[] depsA = a.objects();
Department[] depsB = b.objects();
NSMutableSet ms = new NSMutableSet();

int i;
int j;

for (i = 0; i < depsA.length; i++) {
  for (j = 0; j < depsB.length; j++) {
     ms.addObject(depsA[i]);
     if (depsB[j] != null) {
       if (!depsA[i].departmentName.equals(depsB[j].departmentName)) {
          ms.addObject(depsB[j]);
          depsB[j] = null; // setting null to not to look at this department in B again.
       }
     }
  }
}

You may have to modify this to make it compile and actually work for you.
Avatar of jmc430

ASKER

i slightly modified your code .. but it seems to still be retrieving two identical objects (yes, it is when the department name and the division name are identical).  it compiles, but does not work to remove the duplicate department names and duplicate division names.  what am i doing incorrectly?

        NSArray a = (NSArray)storedValueForKey("affiliations_department");
        NSArray b = (NSArray)storedValueForKey("deptAdmins_department");
        java.util.Enumeration ae = a.objectEnumerator();
        java.util.Enumeration be = b.objectEnumerator();
        String deps = "";
        int i;
        int j;
       
        NSMutableSet ms = new NSMutableSet();
       
        if (a == null && b ==null)
            return NSArray.EmptyArray;
       
        for (i=0;i<a.objects().length;i++){
            Department dep   = (Department)a.objectAtIndex(i);  
            for(j=0;j<b.objects().length;j++){
                Department depb = (Department)b.objectAtIndex(j);          
                ms.addObject(a.objectAtIndex(i));
                if(b.objects()!=null){
                    if(!dep.departmentName().equals(depb.departmentName())){
                        /ms.addObject(b.objectAtIndex(j));  
                    }
                }
            }
        }    
thanks so much for your help!
ASKER CERTIFIED SOLUTION
Avatar of sigmacon
sigmacon

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of jmc430

ASKER

hi sigmacon,

thanks for all of your help!  i tinkered around with your code and this is what i came up with ...

public NSArray getAllDepartments{
        NSArray a = (NSArray)storedValueForKey("affiliations_department");
        NSArray b = (NSArray)storedValueForKey("deptAdmins_department");
        java.util.Enumeration ae = a.objectEnumerator();
        java.util.Enumeration be = b.objectEnumerator();
        String deps = "";
        int i;
        int j;
       
        if (a == null && b ==null)
            return NSArray.EmptyArray;
       
        NSMutableSet ms = new NSMutableSet();

        for (i=0;i<a.objects().length;i++){
            ms.addObjectsFromArray(a);
            Department dep   = (Department)a.objectAtIndex(i);
            NSArray results = a;

            if (results.count() > 2){
                if(dep.divisionName().equals(dep.divisionName()));
                ms.removeObject(a.objectAtIndex(i));
            }
            else if (results.count() == 2){
                Department depF   = (Department)a.objectAtIndex(0);
                Department depL   = (Department)a.objectAtIndex(1);
           
                if(depF.departmentName().equals(depL.departmentName())){
                    if(depF.divisionName().equals(depL.divisionName())){//&& (depF.divisionName().equals(depL.divisionName())));
                    ms.removeObject(a.objectAtIndex(i));
}
                    else if (!(depF.divisionName().equals(depL.divisionName()))){        
                    }
               }
            }
             
            for(j=0;j<b.objects().length;j++){
               
                Department depb = (Department)b.objectAtIndex(j);        
                if(b.objects()!=null){
                    if((dep.departmentName().equals(dep.departmentName())) && (dep.divisionName().equals(dep.divisionName()))){
                        NSArray bresults = b;
                        if (bresults.count() == 2){
                            ms.removeObject(b.objectAtIndex(j));
                        }
                    }
                    if(!(dep.departmentName().equals(depb.departmentName()))){
                        ms.addObject(b.objectAtIndex(j));
                        isAdminDEPT =  true;    
                    }
                }
            }
        }    
 
        NSArray originalListWithDuplicates = ms.allObjects();
        EOSortOrdering ordering1 = new EOSortOrdering("departmentName", EOSortOrdering.CompareAscending);
        NSMutableArray sortOrdering = new NSMutableArray();
        sortOrdering.addObject(ordering1);
        return EOSortOrdering.sortedArrayUsingKeyOrderArray(originalListWithDuplicates, sortOrdering);
    }

  i followed your sample code .. i'm not sure if it's correct .. what do you think?

  for some reason i couldn't set depsA[i] and depsB[j] like you had shown me .. this was my workaround.

  thanks again for your help!  i really appreciate it!!

  best regards,
  jamie