2010-03-16 31 views
16

Tôi có một mảng kết hợp trong awk đó được dân cư như thế này:Sắp xếp một mảng kết hợp trong awk

chr_count[$3]++ 

Khi tôi cố gắng in chr_counts của tôi, tôi sử dụng này:

for (i in chr_count) { 
    print i,":",chr_count[i]; 
} 

Nhưng không đáng ngạc nhiên, thứ tự của tôi không được sắp xếp theo bất kỳ cách nào. Có cách nào dễ dàng để lặp qua các phím được sắp xếp của chr_count không?

+2

Xem http://stackoverflow.com/a/5345056/69663 - nếu bạn có gawk 4, «PROCINFO [" sorted_in "] =" @val_num_asc "' vv rất đơn giản để sử dụng. Hướng dẫn hiển thị nhiều tùy chọn khác nhau nếu bạn muốn giảm dần/tăng dần, theo giá trị/khóa, số/chuỗi, chức năng của chính bạn, v.v. https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning – unhammer

Trả lời

22

Thay vì asort, sử dụng asorti(source, destination) mà sắp xếp các chỉ số vào một mảng mới và bạn sẽ không phải sao chép mảng.

Sau đó, bạn có thể sử dụng các mảng đích như con trỏ vào mảng nguồn.

Ví dụ, bạn sẽ sử dụng nó như thế này:

n=asorti(chr_count, sorted) 
for (i=1; i<=n; i++) { 
     print sorted[i] " : " chr_count[sorted[i]] 
} 
+0

Wow, hoàn toàn quên mất rằng mặc dù đọc ngay qua nó trong tài liệu. Điều này chắc chắn là câu trả lời tốt hơn. – Cascabel

+0

+1 Brilliant !!! –

+1

'asorti' không hoạt động với nawk-20121220-2.fc20.x86_64. –

4

này được lấy trực tiếp từ the documentation:

populate the array data 
# copy indices 
j = 1 
for (i in data) { 
    ind[j] = i # index value becomes element value 
    j++ 
} 
n = asort(ind) # index values are now sorted 
for (i = 1; i <= n; i++) { 
    do something with ind[i]   Work with sorted indices directly 
    ... 
    do something with data[ind[i]]  Access original array via sorted indices 
} 
+0

Xem ra, giải pháp này là thiếu sót vì điều này kết thúc mất các phím có cùng giá trị trong mảng ban đầu. Giải pháp được chấp nhận từ chủ đề khác này có ý tưởng về cách giải quyết: http://stackoverflow.com/a/5345056/95750 – haridsv

+1

@haridsv Không, tôi không nghĩ thế.Câu hỏi này là sắp xếp theo các khóa, không phải các giá trị và không thể có hai giá trị cho cùng một khóa, do đó, không có vấn đề nào ở đây. Câu hỏi khác mà bạn chỉ ra là sắp xếp theo các giá trị (có thể không phải tất cả đều khác biệt), vì vậy nếu bạn cố gắng sử dụng mã này cho điều đó, nó sẽ là một vấn đề. Nhưng đây không phải là thiếu sót nếu bạn sử dụng nó cho những gì nó được viết cho. – Cascabel

+0

Xin lỗi .. Tôi đã đọc sai mã chỉ mục là khóa/giá trị "lật", nhưng sau khi đọc lại, tôi nhận thấy rằng bạn đang sử dụng số không ngừng tăng làm chỉ mục, không phải giá trị ban đầu. Cảm ơn bạn đã quay lại và làm rõ nó. – haridsv

6

Lưu ý rằng asort()asorti() là đặc trưng cho trố mắt, và chưa được biết đến awk. Đối với awk đồng bằng, bạn có thể cuộn sort() của riêng bạn hoặc lấy một từ nơi khác.

11

bạn có thể sử dụng lệnh phân loại. ví dụ.

for (i in data) 
print i ":", data[i] | "sort" 
0

Gần đây tôi đã gặp vấn đề này và thấy rằng với gawk tôi có thể đặt giá trị PROCINFO["sorted_in"] để kiểm soát thứ tự lặp lại. Tôi tìm thấy một danh sách các giá trị hợp lệ cho điều này bằng cách tìm kiếm PROCINFO trực tuyến và hạ cánh trên trang Hướng dẫn này GNU AWK của người sử dụng: https://www.gnu.org/software/gawk/manual/html_node/Controlling-Scanning.html

này liệt kê các lựa chọn có dạng @{key|val}_{num|type|str}_{asc|desc} với:

  • key sắp xếp theo chủ chốt và val sắp xếp theo giá trị.
  • num sắp xếp số lượng, str bởi chuỗi và type theo loại giao.
  • asc cho thứ tự tăng dần và desc cho thứ tự giảm dần.

tôi chỉ đơn giản sử dụng:

PROCINFO["sorted_in"] = "@val_num_desc" 
for (i in map) print i, map[i] 

Và kết quả được sắp xếp theo thứ tự giá trị giảm dần.

Các vấn đề liên quan