【问题标题】:Doubt in action script for Flex: getting unique elements from an ArrayCollectionFlex 的动作脚本中的疑问:从 ArrayCollection 中获取唯一元素
【发布时间】:2011-01-29 07:54:33
【问题描述】:

我有一个如下所述的 ArrayCollection。

        private var initDG:ArrayCollection = new ArrayCollection([
            {fact: "Order #2314", appName: "AA"},

            {fact: "Order #2315", appName: "BB"}

            {fact: "Order #2316", appName: "BB"}
                            ...

            {fact: "Order #2320", appName: "CC"}

            {fact: "Order #2321", appName: "CC"}

            ]);

我想用 ArrayCollection initDG 中的“appName”字段的 UNIQUE VALUES 填充一个组合框。

<mx:ComboBox id="appCombo" dataProvider="{initDG}" labelField="appName"/>

我能想到的一种方法是遍历 Array 对象,并为每个对象检查并将唯一的 appName 条目推送到另一个 Array 中。有没有更好的解决方案?

【问题讨论】:

    标签: apache-flex arraycollection unique-values


    【解决方案1】:

    这听起来不错:

    var unique:Object = {};
    var value:String;
    var array:Array = initDG.toArray();
    var result:Array = [];
    var i:int = 0;
    var n:int = array.length;
    for (i; i < n; i++)
    {
     value = array[i].appName;
     if (!unique[value])
     {
      unique[value] = true;
      result.push(value);
     }
    
    }
    return new ArrayCollection(result);
    

    【讨论】:

    • 应该选择这个作为答案。效果很好!谢谢
    【解决方案2】:

    你可以使用这个类来寻找唯一的数组集合:

    tempArray=_uniqueArray.applyUnqiueKey1(_normalsearchdata.toArray());
    

    "uniqueArray" 这是包名,_normalsearchdata 是 ArrayCollection;

    package{
        import mx.collections.ArrayCollection;
        public class applyUniqueKey{
            private var tempArray:Array;
    
            private var tempIndex = 0;
            public var temp:String;
            public function applyUnqiueKey1(myArray)
    
            {
                tempArray = new Array();
                tempIndex = 0;  
                myArray.sort();
                tempArray[0] = myArray[0];
                tempIndex++;
    
                for(var i=1; i<myArray.length; i++) {
                    if(myArray[i] != myArray[i-1]) {
                        tempArray[tempIndex] = myArray[i];
                        tempIndex++;
                    }
                }
                var temp=String(tempArray.join());
                return new ArrayCollection(tempArray);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      唉,ActionScript 的 Array 中没有 unique() 方法,但你可以这样近似:

      var names:Array = initDG.toArray().map(
          function (e:Object, i:Number, a:Array):String {
              return e.appName;
          }
      );
      
      var uniqueNames:Array = names.filter(
          function (name:String, i:Number, a:Array):Boolean {
                      // Only returns true for the first instance.
              return names.indexOf(name) == i;
          }
      );
      

      请注意,这恰好起作用,因为您正在过滤字符串,这些字符串是按值进行比较的。如果您需要过滤任意对象,这将无效。

      【讨论】:

      • 唯一的问题是匿名函数会带来巨大的性能成本:gskinner.com/talks/quick/#52,而array.indexOf 需要您在每次调用内部迭代数组,这很昂贵。
      • 这是您引用的出色演示文稿。很有意思。我没有意识到匿名函数调用比直接方法调用要昂贵得多。但是该图表中的结果是针对 100,000 次调用的。此代码块需要对匿名函数进行 2 次调用。因此,除非您要迭代数千次以填充您的组合框,否则我几乎不认为性能成本会“巨大”。除非存在明显的性能问题,否则代码可读性比挽救几个周期更重要。
      • 此外,您关于必须为每次比较迭代数组的评论也适用于您最初将唯一值存储在第二个数组中的建议。如果您使用字典,它可能会更快。但同样,除非您的收藏规模很大,否则可能不会有任何明显的性能问题。当您要求“更好”的解决方案时,您关心的是性能吗?
      • 我说错了。为集合中的每个元素调用这些函数。但是,它们只通过一次。在 map 函数内部,它们被存储为局部变量,因此性能应该按照引用调用,而不是匿名调用。
      • 很好,很高兴知道。我只是总是尽量选择最优化的解决方案,只要它一样简单,即使只有 2 次迭代,这样我就可以保持习惯。
      猜你喜欢
      • 2010-12-16
      • 1970-01-01
      • 1970-01-01
      • 2013-02-13
      • 1970-01-01
      • 2011-11-28
      • 2017-04-22
      • 1970-01-01
      相关资源
      最近更新 更多