2017-12-05 2 views

答えて

3

一般的な方法は、文字列をハッシュしてから内容を印刷することです。このアプローチは、emacsで簡単に行うことができます。

;; See the emacs manual for creating a hash table test 
;; https://www.gnu.org/software/emacs/manual/html_node/elisp/Defining-Hash.html 
(defun case-fold-string= (a b) 
    (eq t (compare-strings a nil nil b nil nil t))) 
(defun case-fold-string-hash (a) 
    (sxhash (upcase a))) 

(define-hash-table-test 'case-fold 
    'case-fold-string= 'case-fold-string-hash) 

(defun uniq (beg end) 
    "Print counts of strings in region." 
    (interactive "r") 
    (let ((h (make-hash-table :test 'case-fold)) 
     (lst (split-string (buffer-substring-no-properties beg end) "\n" 
          'omit-nulls " ")) 
     (output-func (if current-prefix-arg 'insert 'princ))) 
    (dolist (str lst) 
     (puthash str (1+ (gethash str h 0)) h)) 
    (maphash (lambda (key val) 
       (apply output-func (list (format "%d: %s\n" val key)))) 
      h))) 

出力そのテキストを選択

4: flower 
1: park 
3: stone 
+0

素敵で速い、これ。あなたがそのヌル・ヌルとライン・トリミングの振る舞いを望んでいるかどうか確信していませんか? – phils

+0

私は 'maphash'シーケンスが未定義であると思いますか? – phils

+0

@philsキー/値によるソートが必要だった場合は、maphash関数に '(push(cons val key)result)'と '(cl-sort results# '>:key#')カー) 'after – jenesaisquoi

0

bashのuniq -cと似ています。

なぜuniq -cを使用しないのですか?

領域が強調表示されている場合、M-| "sort | uniq -c"は、現在の領域でそのコマンドを実行します。結果はミニバッファに表示され、* Messages * bufferにリストされます。プレフィックスargを追加すると、結果が現在のバッファに挿入されます。

+0

' uniq -c'はネイティブ環境によっては利用できません。それが質問の全理由です。 – aartist

2

私はあなたがこれに取ることができるのアプローチがたくさんあると仮定します。これはかなり単純なアプローチです:

(defun uniq-c (beginning end) 
    "Like M-| uniq -c" 
    (interactive "r") 
    (let ((source (current-buffer)) 
     (dest (generate-new-buffer "*uniq-c*")) 
     (case-fold-search nil)) 
    (set-buffer dest) 
    (insert-buffer-substring source beginning end) 
    (goto-char (point-min)) 
    (while (let* ((line (buffer-substring (line-beginning-position) 
              (line-end-position))) 
        (pattern (concat "^" (regexp-quote line) "$")) 
        (count (count-matches pattern (point) (point-max)))) 
      (insert (format "%d " count)) 
      (forward-line 1) 
      (flush-lines pattern) 
      (not (eobp)))) 
    (pop-to-buffer dest))) 
+0

これは、何の役にも立たずに完全に正規表現になっていることを考えると、これは非常に効率的な解決策ではありません。読んだり理解したりするのは簡単なものでなければなりません。 – phils

+0

さらに、このプロセスは、jenesaisquoiのハッシュベースのアプローチに対して、O(n^2)の複雑さ、vs O(n)を持つことに注意してください。 – phils

関連する問題