2013-06-05 35 views
10

Tôi có một danh sách các từ bằng tiếng Ả Rập mà tôi muốn sắp xếp. Tôi đã thử các Collator tiêu chuẩn với Locales khác nhau (như tiếng Anh hoặc tiếng Pháp nhưng không có nhiều hy vọng) và tôi thậm chí đã tạo ra RuleBasedCollator của riêng tôi nhưng vô ích. Dường như việc sắp xếp mặc định dựa trên thứ tự giá trị unicode, mà trong nhiều trường hợp hoạt động nhưng dường như không có trong trường hợp này.Sắp xếp các từ tiếng Ả Rập trong Java

Làm theo hướng dẫn của javadocs, RuleBasedCollator yêu cầu một chuỗi chỉ định các ký tự theo thứ tự bạn muốn chúng được sắp xếp. Tôi tạo ra chuỗi sau lấy mã unicode từ this table:

String arabicLetters = "< \u0623=\uFE83=\uFE84 < \u0628=\uFE8F=\uFE90=\uFE92=\uFE91 < \u062A=\uFE95=\uFE96=\uFE98=\uFE97 < \u062B=\uFE99=\uFE9A=\uFE9C=\uFE9B < \u062C=\uFE9D=\uFE9E=\uFEA0=\uFE9F < \u062D=\uFEA1=\uFEA2=\uFEA4=\uFEA3 < \u062E=\uFEA5=\uFEA6=\uFEA8=\uFEA7 < \u062F=\uFEA9=\uFEAA < \u0630=\uFEAB=\uFEAC < \u0631=\uFEAD=\uFEAE < \u0632=\uFEAF=\uFEB0 < \u0633=\uFEB1=\uFEB2=\uFEB4=\uFEB3 < \u0634=\uFEB5=\uFEB6=\uFEB8=\uFEB7 < \u0635=\uFEB9=\uFEBA=\uFEBC=\uFEBB < \u0636=\uFEBD=\uFEBE=\uFEC0=\uFEBF < \u0637=\uFEC1=\uFEC2=\uFEC4=\uFEC3 < \u0638=\uFEC5=\uFEC6=\uFEC8=\uFEC7 < \u0639=\uFEC9=\uFECA=\uFECC=\uFECB < \u063A=\uFECD=\uFECE=\uFED0=\uFECF < \u0641=\uFED1=\uFED2=\uFED4=\uFED3 < \u0642=\uFED5=\uFED6=\uFED8=\uFED7 < \u0643=\uFED9=\uFEDA=\uFEDC=\uFEDB < \u0644=\uFEDD=\uFEDE=\uFED0=\uFEDF < \u0645=\uFEE1=\uFEE2=\uFEE4=\uFEE3 < \u0646=\uFEE5=\uFEE6=\uFEE8=\uFEE7 < \u0647=\uFEE9=\uFEEA=\uFEEC=\uFEEB < \u0648=\uFEED=\uFEEE < \u064A=\uFEF1=\uFEF2=\uFEF4=\uFEF3 < \u0622=\uFE81=\uFE82 < \u0629=\uFE93=\uFE94 < \u0649=\uFEEF=\uFEF0 < \u0627"; 

Các chữ tiếng Ả Rập có thể mất bốn hình thức tùy thuộc vào vị trí mà họ đang có trong một từ. Vì vậy, những gì tôi đã làm trong chuỗi quy tắc trên là làm cho bằng tất cả 4 hình thức của mỗi chữ cái. Sau đó, tôi chỉ ra thứ tự của các chữ cái tách chúng với '<'. Tôi tưởng tượng rằng đây là cách chính xác để làm điều đó.

Bây giờ, nếu tôi có một bộ sưu tập với các ngày trong tuần (được sắp xếp trong trường hợp này bởi ngày trong tuần, không phải là 'thứ tự abc'):

الأَحَد, الاِثنَين, الثُّلاثاء, الأَربِعاء, الخَميس, الجُمعة,السَّبت 

Kết quả tôi nhận được không được sắp xếp tại tất cả:

الأَحَد, الخَميس, الاِثنَين, الثُّلاثاء, الأَربِعاء, السَّبت, الجُمعة 

Bên cạnh đó, một số lượng từ nhỏ cần một khoảng thời gian đáng kể khiến nó không sử dụng được.

Có ai biết nếu tôi đang làm điều gì đó sai hoặc nếu có thư viện cứu sống đã xử lý việc này?

Tôi đã làm một số googling trước khi viết này và tôi ngạc nhiên tôi đã không tìm thấy một kết quả duy nhất.

Cảm ơn!


CẬP NHẬT với mã:

public static class TranslatableComparator implements java.util.Comparator<Translatable> { 
     @Override 
     public int compare(Translatable t1, Translatable t2) { 

      String sortingRules = "< \u0623=\uFE83=\uFE84 < \u0628=\uFE8F=\uFE90=\uFE92=\uFE91 < \u062A=\uFE95=\uFE96=\uFE98=\uFE97 < \u062B=\uFE99=\uFE9A=\uFE9C=\uFE9B < \u062C=\uFE9D=\uFE9E=\uFEA0=\uFE9F < \u062D=\uFEA1=\uFEA2=\uFEA4=\uFEA3 < \u062E=\uFEA5=\uFEA6=\uFEA8=\uFEA7 < \u062F=\uFEA9=\uFEAA < \u0630=\uFEAB=\uFEAC < \u0631=\uFEAD=\uFEAE < \u0632=\uFEAF=\uFEB0 < \u0633=\uFEB1=\uFEB2=\uFEB4=\uFEB3 < \u0634=\uFEB5=\uFEB6=\uFEB8=\uFEB7 < \u0635=\uFEB9=\uFEBA=\uFEBC=\uFEBB < \u0636=\uFEBD=\uFEBE=\uFEC0=\uFEBF < \u0637=\uFEC1=\uFEC2=\uFEC4=\uFEC3 < \u0638=\uFEC5=\uFEC6=\uFEC8=\uFEC7 < \u0639=\uFEC9=\uFECA=\uFECC=\uFECB < \u063A=\uFECD=\uFECE=\uFED0=\uFECF < \u0641=\uFED1=\uFED2=\uFED4=\uFED3 < \u0642=\uFED5=\uFED6=\uFED8=\uFED7 < \u0643=\uFED9=\uFEDA=\uFEDC=\uFEDB < \u0644=\uFEDD=\uFEDE=\uFED0=\uFEDF < \u0645=\uFEE1=\uFEE2=\uFEE4=\uFEE3 < \u0646=\uFEE5=\uFEE6=\uFEE8=\uFEE7 < \u0647=\uFEE9=\uFEEA=\uFEEC=\uFEEB < \u0648=\uFEED=\uFEEE < \u064A=\uFEF1=\uFEF2=\uFEF4=\uFEF3 < \u0622=\uFE81=\uFE82 < \u0629=\uFE93=\uFE94 < \u0649=\uFEEF=\uFEF0 < \u0627"; 
      RuleBasedCollator col = null; 
      try { 
       col = new RuleBasedCollator(sortingRules); 
      } catch (ParseException e) { 
       //col = (RuleBasedCollator)RuleBasedCollator.getInstance(Locale.FRENCH); 
      } 

      return col.getCollationKey(t1.getTranslation().getText()).compareTo(col.getCollationKey(t2.getTranslation().getText())); 
     } 
    } 
+1

bạn có thể gửi một số chi tiết của mã xin vui lòng? chỉ để chúng ta có thể thấy những gì đang thực sự xảy ra? – shaunvxc

+0

@shaunvxc được cập nhật bằng mã. – Gonan

+0

Tôi không hoàn toàn quen thuộc với RuleBasedCollator, nhưng điều gì xảy ra khi bạn tách các ký tự có giá trị bạn muốn bằng dấu phẩy? Một cái gì đó như thế này: " shaunvxc

Trả lời

5

Bạn không cần phải xác định collator riêng của bạn, chỉ cần sử dụng được xây dựng trong một cho tiếng Ả Rập. Comparator của bạn sau đó trông như thế này

public int compare(Translatable t1, Translatable t2) { 
     Collator.getInstance(new Locale("ar")).compare(t1.getTranslation().getText(), t2.getTranslation().getText()); 
} 

(Bạn có thể kiểm tra xem một collator hiện có sẵn cho tiếng Ả Rập bằng cách duyệt các kết quả từ Collator.getAvailableLocales().)

Như đã đề cập trong các ý kiến, nếu bạn đang lo lắng về hiệu suất mà bạn nên tính toán các khóa đối chiếu, lưu trữ chúng trong các đối tượng Translatable của bạn và sắp xếp chúng thay vào đó.

Nếu bạn thực sự muốn nhìn thấy nơi sự khác biệt là giữa những gì bạn định nghĩa và tiêu chuẩn collator, chỉ cần in ra các quy tắc:

System.out.println((RuleBasedCollator) Collator.getInstance(new Locale("ar"))).getRules(); 
+0

Tôi đã sửa nó. Tôi đã làm một cái gì đó sai trái bản thân mình ở một nơi khác trong mã. Về cơ bản tôi đã sửa đổi danh sách trước khi phân loại nó với phương pháp này và do đó tôi đã nhận được kết quả sai. Như đề cập đến rxg, không cần phải sử dụng một Collator đặc biệt cho việc này. Việc sắp xếp sẽ làm việc lấy các giá trị Unicode của các ký tự, và vì chúng được sắp xếp theo thứ tự bảng chữ cái, đó là nó. Về hiệu suất, thực sự tôi đã không nhận thấy rằng tôi đã tạo ra một đối tượng cho mỗi so sánh. Tôi đã thay đổi nó thành những gì mà SuperEB đề xuất và bây giờ phải mất chưa đầy một giây. Cảm ơn! – Gonan

+0

Vì đây là những gì tôi đã làm trước khi thử phương pháp RuleBasedCollator, và về cơ bản vì đây là cách để làm điều đó, tôi sẽ đánh dấu nó là câu trả lời. – Gonan

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