views:

271

answers:

3

Hi!

I am searching for a method to intersect my array collections.

I have one collection: allItems and another subSet. I want to create another ArrayCollection where all items which do not exist in subSet will be stored. Is there a way to do this?

A: 

For getting a collection of items not in another you need a set difference algorithm (allItems minus subSet).

public function minus(a:ArrayCollection, b:ArrayCollection):ArrayCollection {
    var result:ArrayCollection = new ArrayCollection()

    for each (i in a) {
        if (!b.contains(i)) {
            result.addItem(i)
        }
    }

    return result
}
Eemeli Kantola
Is there an `add` method in `ArrayCollection`? Shouldn't it be `addItem`?
Amarghosh
Yeah, you're right. Fixed :)
Eemeli Kantola
about difference and itersection: let A and B be two sets ... the intersection of A and B is equal to A minus B if and only if A is empty ... if B is a subset of A, then their intersection is B, and A minus B is the complement of B with respect to A ...
back2dos
Right, my bad. Removed the erroneus sentence altogether :) The original question's title is anyway confusing.
Eemeli Kantola
+1  A: 
var allLength:Number = allItems.length;
var intersection:ArrayCollection = new ArrayCollection();
for(var i:Number = 0; i < allLength; i++)
  if(subSet.getItemIndex(allItems.getItemAt(i)) == -1)
    intersection.addItem(allItems.getItemAt(i));

Note that this will work only if the subset contains the same objects as the super set. If the subset contains different objects with the same property values as of the super set object, you are gonna have to compare their properties separately.

Amarghosh
+1  A: 

working answer provided by eemeli ... here is an alternative implementation optimized for speed (array access instead of calls) and scalability (approach provides O(m+n) instead of O(m*n))...

public static function difference(a:ArrayCollection, b:ArrayCollection):ArrayCollection {
    var entry:*, map:Dictionary = new Dictionary(), intersection:Array = [];
    for each (entry in a.source) map[entry] = entry;
    for each (entry in b.source) delete map[entry];
    for each (entry in map) intersection.push(entry);
    return new ArrayCollection(intersection);
}

greetz

back2dos

back2dos
+1 for the optimization
Amarghosh