Nhanh chóng rẽ nhánh, chỉnh sửa trực tuyến và gửi yêu cầu kéo cho trang này. Yêu cầu tài khoản GitHub đã đăng nhập. Điều này hoạt động tốt cho những thay đổi nhỏ. Nếu bạn muốn thực hiện những thay đổi lớn hơn, bạn có thể cân nhắc sử dụng bản sao cục bộ
Mảng kết hợp có chỉ mục không nhất thiết phải là số nguyên và có thể được điền thưa thớt. Chỉ mục cho một mảng kết hợp được gọi là khóa và loại của nó được gọi là KeyType
Mảng kết hợp được khai báo bằng cách đặt KeyType trong [ ] của khai báo mảng
Cả KeyTypes và kiểu phần tử của một mảng kết hợp đều không thể là kiểu hàm hoặc void
Xác định thực hiện. Các mảng kết hợp tích hợp không bảo toàn thứ tự của các khóa được chèn vào mảng. Cụ thể, trong một vòng lặp foreach, thứ tự lặp lại các phần tử thường không được chỉ định
auto aa = [21u: "he", 38: "ho", 2: "hi"]; static assert[is[typeof[aa] == string[uint]]]; assert[aa[2] == "hi"];
Thấy
Các khóa cụ thể trong một mảng kết hợp có thể được xóa bằng chức năng xóa
aa.remove["hello"];
remove[key] không làm gì nếu key đã cho không tồn tại và trả về false. Nếu khóa đã cho tồn tại, nó sẽ xóa nó khỏi AA và trả về true
Tất cả các phím có thể được gỡ bỏ bằng cách sử dụng phương pháp rõ ràng
Trả về một con trỏ tới giá trị nếu khóa nằm trong mảng kết hợp hoặc null nếu không
Hành vi không xác định. Điều chỉnh con trỏ trỏ đến trước hoặc sau phần tử có địa chỉ được trả về, sau đó hủy bỏ hội nghị
Các lớp có thể được sử dụng làm KeyType. Để điều này hoạt động, định nghĩa lớp phải ghi đè lên các hàm thành viên sau của đối tượng lớp
- size_t toHash[] @trusted nothrow
- bool opEquals[Đối tượng]
Lưu ý rằng tham số cho opEquals thuộc loại Đối tượng, không phải loại của lớp mà nó được định nghĩa
Ví dụ
class Foo { int a, b; override size_t toHash[] { return a + b; } override bool opEquals[Object o] { Foo foo = cast[Foo] o; return foo && a == foo.a && b == foo.b; } }
Xác định thực hiện. opCmp không được sử dụng để kiểm tra sự bằng nhau của mảng kết hợp. Tuy nhiên, vì opEquals hoặc opCmp thực tế được gọi không được quyết định cho đến khi chạy, nên trình biên dịch không thể luôn phát hiện các hàm không khớp. Do các vấn đề cũ, trình biên dịch có thể từ chối loại khóa mảng kết hợp ghi đè opCmp chứ không phải opEquals. Hạn chế này có thể được gỡ bỏ trong các phiên bản sau
Hành vi không xác định
- Nếu toHash phải nhất quán có cùng giá trị khi opEquals trả về true. Nói cách khác, hai đối tượng được coi là bằng nhau phải luôn có cùng giá trị băm. Nếu không, hành vi không xác định sẽ dẫn đến
Thực hành tốt nhất
- Sử dụng các thuộc tính @safe, @nogc, pure, const và phạm vi càng nhiều càng tốt trên phần ghi đè toHash và opEquals
Nếu KeyType là một loại cấu trúc hoặc liên kết, một cơ chế mặc định được sử dụng để tính toán hàm băm và so sánh của nó dựa trên các trường của giá trị cấu trúc. Một cơ chế tùy chỉnh có thể được sử dụng bằng cách cung cấp các chức năng sau với tư cách là thành viên cấu trúc
size_t toHash[] const @safe pure nothrow; bool opEquals[ref const typeof[this] s] const @safe pure nothrow;
Ví dụ
import std.string; struct MyString { string str; size_t toHash[] const @safe pure nothrow { size_t hash; foreach [char c; str] hash = [hash * 9] + c; return hash; } bool opEquals[ref const MyString s] const @safe pure nothrow { return std.string.cmp[this.str, s.str] == 0; } }
Các chức năng có thể sử dụng @trusted thay vì @safe
Xác định thực hiện. opCmp không được sử dụng để kiểm tra sự bằng nhau của mảng kết hợp. Vì lý do này và vì các lý do kế thừa, khóa mảng kết hợp không được phép xác định một opCmp chuyên biệt, nhưng bỏ qua một opEquals chuyên biệt. Hạn chế này có thể được loại bỏ trong các phiên bản tương lai của D
Hành vi không xác định
- Nếu toHash phải nhất quán có cùng giá trị khi opEquals trả về true. Nói cách khác, hai cấu trúc được coi là bằng nhau phải luôn có cùng giá trị băm. Nếu không, hành vi không xác định sẽ dẫn đến
Thực hành tốt nhất
- Sử dụng các thuộc tính @nogc càng nhiều càng tốt trên phần ghi đè toHash và opEquals
Khi quyền truy cập lập chỉ mục AA xuất hiện ở phía bên trái của toán tử gán, nó được xử lý đặc biệt để đặt mục nhập AA được liên kết với khóa
Nếu loại giá trị được gán tương đương với loại phần tử AA
- Nếu khóa chỉ mục chưa tồn tại trong AA, một mục nhập AA mới sẽ được phân bổ và nó sẽ được khởi tạo với giá trị được chỉ định
- Nếu khóa lập chỉ mục đã tồn tại trong AA, cài đặt sẽ chạy gán bình thường
Nếu loại giá trị được gán không tương đương với loại phần tử AA, thì biểu thức có thể gọi quá tải toán tử với quyền truy cập lập chỉ mục thông thường
Tuy nhiên, nếu loại phần tử AA là một cấu trúc hỗ trợ lệnh gọi hàm tạo ngầm định từ giá trị được gán, thì cấu trúc ngầm định được sử dụng để đặt mục nhập AA
Điều này được thiết kế để tái sử dụng bộ nhớ hiệu quả với một số cấu trúc ngữ nghĩa giá trị, ví dụ:. tiêu chuẩn. cố chấp. BigIntKhi truy cập AA yêu cầu phải có một giá trị tương ứng với khóa, một giá trị phải được xây dựng và chèn vào nếu không có. Hàm yêu cầu cung cấp một phương tiện để xây dựng một giá trị mới thông qua một đối số lười biếng. Đối số lười biếng được đánh giá khi không có khóa. Thao tác yêu cầu tránh phải thực hiện nhiều lần tra cứu chính
Đôi khi cần phải biết liệu giá trị đã được xây dựng hay đã tồn tại. Hàm yêu cầu không cung cấp tham số boolean để cho biết liệu giá trị có được tạo hay không mà thay vào đó cho phép tạo thông qua hàm hoặc đại biểu. Điều này cho phép sử dụng bất kỳ cơ chế nào như được minh họa bên dưới
class C{} C[string] aa; bool constructed; auto a = aa.require["a", { constructed=true; return new C;}[]]; assert[constructed == true]; C newc; auto b = aa.require["b", { newc = new C; return newc;}[]]; assert[b is newc];
Thông thường, việc cập nhật một giá trị trong một mảng kết hợp được thực hiện đơn giản với câu lệnh gán
Đôi khi cần phải thực hiện các thao tác khác nhau tùy thuộc vào việc một giá trị đã tồn tại hay cần được xây dựng. Hàm cập nhật cung cấp phương tiện để xây dựng giá trị mới thông qua đại biểu tạo hoặc cập nhật giá trị hiện có thông qua đại biểu cập nhật. Thao tác cập nhật tránh phải thực hiện nhiều lần tra cứu chính
Để biết chi tiết, xem
GHI CHÚ. Chưa thực hiện.immutable long[string] aa = [ "foo": 5, "bar": 10, "baz": 2000 ]; unittest { assert[aa["foo"] == 5]; assert[aa["bar"] == 10]; assert[aa["baz"] == 2000]; }
Các mảng kết hợp bất biến thường được mong muốn, nhưng đôi khi việc khởi tạo phải được thực hiện trong thời gian chạy. Điều này có thể đạt được với một hàm tạo [hàm tạo tĩnh tùy thuộc vào phạm vi], một mảng kết hợp bộ đệm và giả sửUnique
Mảng liên kết mặc định là null và được tạo khi gán cặp khóa/giá trị đầu tiên. Tuy nhiên, sau khi được tạo, một mảng kết hợp có ngữ nghĩa tham chiếu, nghĩa là việc gán một mảng này cho một mảng khác sẽ không sao chép dữ liệu. Điều này đặc biệt quan trọng khi cố gắng tạo nhiều tham chiếu đến cùng một mảng
Thuộc tính cho mảng kết hợp là
Thuộc tính mảng kết hợp Thuộc tínhMô tả. sizeofTrả về kích thước của tham chiếu đến mảng kết hợp; . lengthTrả về số giá trị trong mảng kết hợp. Không giống như mảng động, nó chỉ đọc. dupTạo một mảng kết hợp mới có cùng kích thước và sao chép nội dung của mảng kết hợp vào đó. keysTrả về mảng động, các phần tử trong đó là các khóa trong mảng kết hợp. valueTrả về mảng động, các phần tử của nó là các giá trị trong mảng kết hợp. rehashSắp xếp lại mảng kết hợp tại chỗ để tra cứu hiệu quả hơn. rehash có hiệu quả, ví dụ, khi chương trình tải xong một bảng biểu tượng và bây giờ cần tra cứu nhanh trong đó. Trả về một tham chiếu đến mảng được sắp xếp lại. clearXóa tất cả các khóa và giá trị còn lại khỏi một mảng kết hợp. Mảng không được băm lại sau khi xóa, để cho phép sử dụng lại bộ lưu trữ hiện có. Điều này sẽ ảnh hưởng đến tất cả các tham chiếu đến cùng một phiên bản và không tương đương với hủy [aa] chỉ đặt tham chiếu hiện tại thành null. byKey[] Trả về một phạm vi chuyển tiếp phù hợp để sử dụng làm ForeachAggregate thành a sẽ lặp qua các khóa của mảng kết hợp. byValue[] Trả về một phạm vi chuyển tiếp phù hợp để sử dụng làm ForeachAggregate thành a sẽ lặp qua các giá trị của mảng kết hợp. byKeyValue[] Trả về một phạm vi chuyển tiếp phù hợp để sử dụng làm ForeachAggregate thành một phạm vi sẽ lặp qua các cặp khóa-giá trị của mảng kết hợp. Các cặp được trả về được biểu thị bằng một loại mờ với. chìa khóa và. thuộc tính giá trị để truy cập khóa và giá trị của cặp tương ứng. Lưu ý rằng đây là giao diện cấp thấp để lặp qua mảng kết hợp và không tương thích với loại trong Phobos. Để tương thích với Tuple, hãy sử dụng thay thế. get[Key key, lazy Value defVal]Tra cứu key; . yêu cầu [Khóa chính, giá trị Giá trị lười biếng] Tra cứu khóa; . cập nhật[Khóa chính, Giá trị đại biểu[] tạo, Cập nhật giá trị đại biểu[Giá trị]] Tra cứu khóa;too many cooks too many ingredients
import std.algorithm; import std.stdio; void main[] { ulong[string] dictionary; ulong wordCount, lineCount, charCount; foreach [line; stdin.byLine[KeepTerminator.yes]] { charCount += line.length; foreach [word; splitter[line]] { wordCount += 1; if [auto count = word in dictionary] *count += 1; else dictionary[word.idup] = 1; } lineCount += 1; } writeln[" lines words bytes"]; writefln["%8s%8s%8s", lineCount, wordCount, charCount]; const char[37] hr = '-'; writeln[hr]; foreach [word; sort[dictionary.keys]] { writefln["%3s %s", dictionary[word], word]; } }
Xem wc để biết phiên bản đầy đủ
Một Mảng kết hợp có thể được lặp lại theo kiểu khóa/giá trị bằng cách sử dụng một. Ví dụ: số lần xuất hiện của tất cả các chuỗi con có thể có độ dài 2 [còn gọi là 2-mers] trong một chuỗi sẽ được tính