我有一个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');
我需要以某种方式遍历数组以找到所有重叠对(任何共享公共对的对)。
例如,ItemA
与ItemB
和ItemC
配对,因此它们属于一个组。 ItemC
也与ItemD
和ItemE
配对,因此他们也需要成为第一组的一部分。
ItemF
,ItemG
和ItemH
与第一组中的任何项目都不重叠,因此需要将它们放入自己的群组中。
结果数组必须是:
groups[0] = Array('ItemA', 'ItemB', 'ItemC', 'ItemD', 'ItemE'); groups[1] = Array('ItemF', 'ItemG', 'ItemH');
感谢您提供任何帮助和建议!
修改
有点背后的故事;我正在尝试将2D中彼此重叠的影片剪辑组合在一起以创建组或群集(可能是更好的词)。
因此,如果我在舞台上有3个动画片段并且ClipA与ClipB重叠并且ClipB与ClipC重叠(但ClipA不直接与ClipC重叠),则它们应该全部组合在一起,因为它们都是同一个集群的一部分。这样,如果新剪辑与群集中的任何单个项重叠,它将被添加到该组的数组中。
我已经找到了代码来找到产生这个对列表的重叠元素,现在我需要将它压缩成整齐的组。
答案 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;
}