8

我想在哈希表中的值上映射一个函数,如下所示:

(hash-map add1 (hash "apple" 1 "pear" 2))
=> #hash(("apple" . 2) ("pear" . 3))

是否有库函数可以做到这一点?最好有一个也可以处理不可变哈希表。

我查看了PlaneT,但没有看到任何东西。

现在,如果这真的不存在,我会继续写下去。把这个带入球拍的礼仪是什么?我只是在 github 上 fork 并将其添加到标准库(和文档!)并提交拉取请求?还是我应该先把它变成一个planeT,然后再要求它搬进来?我想帮忙,但我只是不知道什么是“正确”的方法。

4

4 回答 4

8

有一个哈希映射,但它返回一个列表 [ 1 ]

您必须自己编写hash-map才能完全按照您的意愿进行操作。

#lang racket

(define (new-hash-map f h)
  (make-immutable-hash (hash-map h (λ (k v) (cons k (f v))))))

(new-hash-map add1 (hash "apple" 1 "pear" 2))

; => '#hash(("pear" . 3) ("apple" . 2))

您可能感兴趣的另一种形式是 for/hash [ 2 ]:

#lang racket

(define (new-hash-map2 f h)
  (for/hash ([(k v) (in-hash h)]) (values k (f v))))

(new-hash-map2 add1 (hash "apple" 1 "pear" 2))

; => '#hash(("pear" . 3) ("apple" . 2))

如果你觉得这个功能应该包含在 Racket 中,欢迎使用补丁!最好的贡献方式是在 github 上 fork 并提交拉取请求。

于 2013-01-31T18:58:21.253 回答
2

在 Racket 中,您可以使用hash-map高阶过程,它通常返回一个列表,其中包含作为参数接收的过程的应用程序产生的值,但它可以适用于就地修改地图。例如:

(define h (make-hash))
(hash-set! h "apple" 1)
(hash-set! h "pear" 2)

h
=> '#hash(("pear" . 2) ("apple" . 1))

诀窍是传递lambda具有适当功能的 a :

(hash-map h (lambda (key value)
              (let ((newval (add1 value)))
                (hash-set! h key newval)
                newval)))

h
=> '#hash(("pear" . 3) ("apple" . 2))

对于更通用的解决方案,请尝试以下实现:

(define (mutable-hash-map! hash proc)
  (hash-map hash (lambda (key value)
                   (hash-set! hash key (proc value))))
  (void))
于 2013-01-31T18:54:51.213 回答
2

您可以使用in-hash-values遍历哈希表的值,并使用常规for 循环来映射它们。该函数in-hash-values接受一个散列并返回一个值序列,然后可以用for循环遍历它。

例子:

(for/list ([elt (in-hash-values (hash "apple" 1 "pear" 2))])
  (add1 elt))

同样,您可以使用sequence-map,尽管您得到的是另一个序列而不是列表:

(sequence-map add1 (in-hash-values (hash "apple" 1 "pear" 2)))
于 2013-01-31T18:58:55.403 回答
2

由于hash-map创建了一个此处不需要的列表,我宁愿使用hash-for-each

(define (hash-update-all! h func)
  (hash-for-each
    h
    (lambda (k v) (hash-set! h k (func v)))))

(define table (make-hash '((a . 1) (b . 2) (c . 3))))

(hash-update-all! table (curry * 100))

table

 ==> '#hash((c . 300) (a . 100) (b . 200))

编辑:我忘记了for可以处理哈希表:

(define (hash-update-all! h func)
  (for ([(k v) h])   (hash-set! h k (func v))))

(hash-update-all! table (curryr / 10))

table

 ==> '#hash((c . 30) (a . 10) (b . 20))
于 2013-01-31T21:11:29.763 回答