将对列表转换为AS3中的数组

时间:2010-11-29 06:55:39

标签: arrays actionscript-3 flash

我有一个ActionScript 3数组,列出了这样的项目对:

pairs[0] = Array('ItemA', 'ItemB');
pairs[1] = Array('ItemA', 'ItemC');
pairs[2] = Array('ItemC', 'ItemD');
pairs[3] = Array('ItemC', 'ItemE');
pairs[4] = Array('ItemF', 'ItemG');
pairs[5] = Array('ItemF', 'ItemH');

我需要以某种方式遍历数组以找到所有重叠对(任何共享公共对的对)。

例如,ItemAItemBItemC配对,因此它们属于一个组。 ItemC也与ItemDItemE配对,因此他们也需要成为第一组的一部分。

ItemFItemGItemH与第一组中的任何项目都不重叠,因此需要将它们放入自己的群组中。

结果数组必须是:

groups[0] = Array('ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE');
groups[1] = Array('ItemF', 'ItemG', 'ItemH');

感谢您提供任何帮助和建议!

修改

有点背后的故事;我正在尝试将2D中彼此重叠的影片剪辑组合在一起以创建组或群集(可能是更好的词)。

因此,如果我在舞台上有3个动画片段并且ClipA与ClipB重叠并且ClipB与ClipC重叠(但ClipA不直接与ClipC重叠),则它们应该全部组合在一起,因为它们都是同一个集群的一部分。这样,如果新剪辑与群集中的任何单个项重叠,它将被添加到该组的数组中。

我已经找到了代码来找到产生这个对列表的重叠元素,现在我需要将它压缩成整齐的组。

3 个答案:

答案 0 :(得分:1)

以下示例的算法应该有效。

注意:这是编写此代码的最有效或最简洁的方法(它肯定比它需要的更重复),但我想为此示例保持清晰和简单。 [另外,我还没有测试过这段代码 - 它只是伪代码 - 所以如果你发现错误,请告诉我,我会修复它)

var idx:Object = new Object;
var groups:Array = new Array();
for( var i:int = 0; i<pairs.length; ++i ) {
   var onePair:Array = pairs[i];

   // which groups do the two items belong to?
   var g1:Array = idx[onePair[0]];
   var g2:Array = idx[onePair[1]];

   if( !g1 ) {
     // if item #1 is not yet in a group, then add it to item #2's
     // existing group, or if neither group exists yet, just create a new one
     g1 = g2;
     if( !g1 ) {
        g1 = [];
        groups.push(g1);
     }
     g1.push( onePair[0] );

     // ensure that the idx properly reflects the location of the new item
     idx[onePair[0]] = g1;
   }

   // now do the same for the second item... but g1 will never be null, so
   // this case is a little simpler.
   if( !g2 ) {
     g2 = g1;
     g2.push( onePair[1] );
     idx[onePair[1]] = g2;
   }

   if( g1 != g2 ) {
      // now, if they're not already the same group, then merge the two
      // groups, and update the idx to reflect the merge.

      for( var z:int=0; z<g2.length; ++z ) {
         idx[g2[z]] = g1;
         g1.push( g2[z] );
         g2.splice(0);
      }
   }
}

groups最终将成为一个数组数组,就像你要求的那样 - 但是会有一些空数组可以被丢弃。只修剪(或忽略)空的,你就会有你的小组。

这里的基本思想是,idx提供了一个查找表,在整个索引过程中,它指示任何给定的项目,它所在的组(如果有的话)。这允许我们确定先前是否遇到过某个项目,如果是,则使用它现有的组。

答案 1 :(得分:1)

您可以使用Object来跟踪对一组和一组的关联,关键是您的对中的每个项目。

这是一个创作作品的litle片段:

var pairs:Array=[];
pairs[0] = ['ItemA', 'ItemB'];
pairs[1] = ['ItemA', 'ItemC'];
pairs[2] = ['ItemC', 'ItemD'];
pairs[3] = ['ItemC', 'ItemE'];
pairs[4] = ['ItemF', 'ItemG'];
pairs[5] = ['ItemF', 'ItemH'];


// will contain group created
var groups:Array=[];

// will contain association between a pair item and a group
var pair2group:Object={};

// function that turn pairs into groups
function makeGroups(pairs:Array):void{
    var pairLen:int = pairs.length;

    for (var i:int=0;i<pairLen;i++){
        var pair:Array = pairs[i];
        var item1:String = pair[0];
        var item2:String = pair[1];

        var group:Array = pair2group[item1];

        // is first pair item already in a group
        if (group == null) {
            // no so create a new group
            group=[];

            // create the association
            pair2group[item1] = group;

            // add the item to the group we have created
            group.push(item1);

            // add it to all the groups 
            groups.push(group);
        }

        // is the second pair item into a grouo
        if (pair2group[item2] == null) {
            // no so add it to the group where the first item belong
            group.push(item2);

            // create the association for the second item
            pair2group[item2] = group;
        }
    }
}

// ---- test
makeGroups(pairs);
trace(groups.length);
trace(groups[0]);
trace(groups[1]);

答案 2 :(得分:0)

经过大量的游戏后,我想出了解决方案。

这将采用具有对的2D overlapArray并生成具有唯一值的组列表。

我使用in_array()函数复制PHP的便捷函数,以查找某个项目是否已存在于数组中。

for each(var pair:Array in overlapArray) {
    var pairInGroup = false;
    for each(var group:Array in overlapArrayGroups) {
        if(in_array(pair[0],group) || in_array(pair[1],group)) {
            if(!in_array(pair[0],group)) {
                group.push(pair[0]);
            }
            if(!in_array(pair[1],group)) {
                group.push(pair[1]);
            }
            pairInGroup = true;
        }
    }
    if(!pairInGroup) {
        overlapArrayGroups.push(pair);
    }
}

in_array()功能:

public static function in_array( needle:String, haystack:Array ):Boolean {
    for( var a = 0; a < haystack.length; a++ ) {
        if( haystack[a] == needle ) {
            return true;
        } else if( haystack[a] is Array ) {
            return in_array(needle, haystack[a]);
        }
    }
    return false;
}