2011-09-22 19 views
5

Ora devo copiare il hastable ad una lista prima di smistamento:Qual è il modo migliore per ordinare un hashtable in base al valore?

(defun good-red() 
    (let ((tab (make-hash-table)) (res '())) 
    (dotimes (i 33) (setf (gethash (+ i 1) tab) 0)) 
    (with-open-file (stream "test.txt") 
     (loop for line = (read-line stream nil) 
      until (null line) 
      do 
       (setq nums (butlast (str2lst (substring line 6)))) 
       (dolist (n nums) (incf (gethash n tab))) 
       )) 
    **(maphash #'(lambda (k v) (push (cons k v) res)) tab)** 
    (setq sort-res (sort res #'< :key #'cdr)) 
    (reverse (nthcdr (- 33 18) (mapcar #'car sort-res))))) 

proposito, qual è il modo migliore per andare a prendere i primi N elementi di una lista?

+1

Qual è la tua domanda? Quello nel titolo o quello nei contenuti? –

+0

Non sarebbe più costruttivo rispondere semplicemente a quello nel titolo e/o quello nei commenti? – Paralife

risposta

10

La risposta di Vatine è tecnicamente corretta, ma probabilmente non super utile per il problema immediato di qualcuno che fa questa domanda. Il caso comune di utilizzare una tabella hash per contenere una raccolta di contatori, quindi selezionando i primi N elementi di punteggio può essere fatto in questo modo:

;; convert the hash table into an association list 
(defun hash-table-alist (table) 
    "Returns an association list containing the keys and values of hash table TABLE." 
    (let ((alist nil)) 
    (maphash (lambda (k v) 
       (push (cons k v) alist)) 
      table) 
    alist)) 

(defun hash-table-top-n-values (table n) 
    "Returns the top N entries from hash table TABLE. Values are expected to be numeric." 
    (subseq (sort (hash-table-alist table) #'> :key #'cdr) 0 n)) 

La prima funzione restituisce il contenuto di una tabella hash come una serie di cons 'd coppie in una lista, che è chiamata una lista di associazioni (la rappresentazione tipica della lista per coppie chiave/valore). La maggior parte degli appassionati di Lisp ha già una variazione di questa funzione perché è un'operazione così comune. Questa versione proviene dalla libreria Alexandria, che è molto utilizzata nella comunità CL.

La seconda funzione utilizza SUBSEQ per acquisire i primi N elementi dall'elenco restituito ordinando l'elenco restituito dalla prima funzione utilizzando il CDR di ogni coppia come chiave. Modifica: la chiave per # 'auto sarebbe ordinata per i tasti hash, cambiando #'> a # '< invertirà l'ordinamento.

2

Una tabella hash è intrinsecamente non ordinata. Se lo si desidera ordinare, è necessario inizializzare una sorta di struttura dati ordinata con i contenuti.

Se si desidera recuperare i primi N elementi di una sequenza, c'è sempre SUBSEQ.

Problemi correlati