2010-03-05 28 views

Trả lời

32

Không có phương pháp tích hợp để lấy kích thước/chiều dài/số của từ điển AS3. Có cách giải quyết: ví dụ, bạn có thể tạo một lớp từ điển tùy chỉnh mở rộng hoặc kết thúc lớp flash.utils.Dictionary, thêm chức năng truy cập. Bạn có thể quản lý tính là mục được thêm/gỡ bỏ, hoặc đếm theo yêu cầu sử dụng đơn giản Đối với vòng lặp:

public static function countKeys(myDictionary:flash.utils.Dictionary):int 
{ 
    var n:int = 0; 
    for (var key:* in myDictionary) { 
     n++; 
    } 
    return n; 
} 
+1

Quá xấu, phải xây dựng một wrapper. –

+47

Tôi nên làm gì để downvote Adobe để thực hiện việc này? –

+1

Điều cần thiết là tránh được các chuỗi trong các vòng lặp, tức là những gì sẽ xảy ra khi lặp qua một mảng với for..in. – Brilliand

0

Người ta sẽ lý tưởng chỉ cần thực hiện một wrapper xung quanh từ điển mở rộng lớp Proxy. Điều đó cho phép bạn ghi đè và chặn việc bổ sung và loại bỏ các thuộc tính khỏi Từ điển, cho phép lớp Từ điển mới được sử dụng chính xác như bản gốc, với cùng cú pháp và khả năng, với việc bổ sung hàm chiều dài trả về số lượng phím.

Triển khai này hoạt động như sau. Khi một thuộc tính được thiết lập hoặc bị xóa, nó sẽ kiểm tra xem thuộc tính đã tồn tại hay chưa (cho dù nó hoàn toàn bằng undefined) và gia số hoặc giảm đi bộ đếm chiều dài nội bộ tương ứng. Triển khai này cũng tự động xóa mục nhập khi giá trị của nó được đặt thành không xác định cho tính nhất quán.

Tôi đã viết trình bao bọc từ điển này chỉ dành cho câu hỏi này; nó mất khoảng 5 phút, và nó cung cấp một hàm chiều dài trả về độ dài. Tôi đã chọn để làm cho nó một chức năng chứ không phải là một tài sản để nó không can thiệp với tên tài sản hoặc liệt kê các thuộc tính của từ điển.

KHÔNG SỬ DỤNG THỰC HIỆN NÀY; SỬ DỤNG MỘT R THNG THEO D ITI IT. Tôi giải thích lý do tại sao bên dưới.

package flos.utils 
{ 
    import flash.utils.flash_proxy; 
    import flash.utils.Proxy; 

    public class Dictionary extends Proxy 
    { 
     private var d:flash.utils.Dictionary; 
     private var _length:int = 0; 

     public function Dictionary(weakKeys:Boolean = false) 
     { 
      d = new flash.utils.Dictionary(weakKeys); 
     } 

     public function length():int 
     { 
      return _length; 
     } 

     override flash_proxy function getProperty(name:*):* 
     { 
      return d[name]; 
     } 

     override flash_proxy function setProperty(name:*, value:*):void 
     { 
      if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted 
      { 
       delete this[name]; 
       return; 
      } 
      if (d[name] === undefined) 
       _length++; 
      d[name] = value; 
     } 

     override flash_proxy function deleteProperty(name:*):Boolean 
     { 
      if (d[name] !== undefined) 
      { 
       delete d[name]; 
       _length--; 
       return true; 
      } 
      return false; 
     } 
    } 
} 

SỰ TỪ BỎ: Việc thực hiện ở trên, mặc dù phương pháp hứa hẹn nhất mà có thể làm việc trên lý thuyết, cuối cùng là một ngõ cụt, vì từ điển vốn không phù hợp với phương pháp giao diện Proxy.

Thứ nhất, setProperty, getProperty, và deleteProperty phương pháp xuất hiện để nhận untyped name thông số, nhưng họ thực sự mạnh mẽ gõ QName đối tượng, trong đó chủ yếu hạn chế phím của bạn để String tên loại, giống như Object và Mảng liên kết. Dictionary không bị ràng buộc bởi giới hạn này và cho phép sử dụng các cá thể đối tượng dưới dạng các khóa duy nhất, do đó, nó vốn không tương thích với các phương thức lớp Proxy. Tài liệu của lớp Từ điển cũng có một ghi chú duy nhất, và nó nói rõ ràng rằng các đối tượng QName không thể được sử dụng như các khóa.

Tương tự, phương pháp Proxy nextName ngăn bạn liệt kê tất cả các phím Dictionary vì cùng một lý do, vì nó có giá trị trả về kiểu mạnh là String. Vì vậy, ngay cả khi setProperty, getProperty thực sự chấp nhận các phím không được nhập mã cho tên, bạn vẫn sẽ không thể truy xuất chúng bằng cách liệt kê vì phương thức nextName chỉ trả về chuỗi loại. Dictionary chỉ đơn giản là trong một lớp học của riêng mình. Điều tốt nhất bạn có thể làm là triển khai trình bao bọc giống như từ điển hiển thị từ điển cơ bản để liệt kê, nhưng những thứ khác yêu cầu gọi phương thức addKey/removeKey rõ ràng với tên và giá trị chưa được nhập, thay vì sử dụng hành vi Proxy.

Với tất cả những điều trên, việc thực hiện tốt hơn như sau, khi bạn thao tác từ điển bằng cách gọi phương thức như getValue/setValue/removeValue và có quyền truy cập vào khóa liệt kê cũng như thuộc tính độ dài:

public class Dictionary 
{ 
    private var d:flash.utils.Dictionary; 
    private var _keys:Array; 

    public function Dictionary(weakKeys:Boolean = false) 
    { 
     d = new flash.utils.Dictionary(weakKeys); 
     _keys = new Array(); 
    } 

    public function get keys():Array 
    { 
     return _keys.concat(); //return copy of keys array 
    } 

    public function get length():int 
    { 
     return _keys.length; 
    } 

    public function containsKey(key:*):Boolean 
    { 
     return d[key] !== undefined; 
    } 

    public function setValue(key:*, value:*):void 
    { 
     if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted 
     { 
      removeValue(key); 
      return; 
     } 
     if (d[key] === undefined) 
     { 
      _keys.push(key); 
     } 
     d[key] = value; 
    } 

    public function getValue(key:*):* 
    { 
     return d[key]; 
    } 

    public function removeValue(key:*):Boolean 
    { 
     if (d[key] !== undefined) 
     { 
      delete d[key]; 
      var i:int = _keys.indexOf(key); 
      if (i > -1) 
       _keys.splice(i, 1); 
      return true; 
     } 
     return false; 
    } 
0

Bạn có thể sử dụng DictionaryUtil:

var dictionaryLength : int = DictionaryUtil.getKeys(d).length; 
Các vấn đề liên quan