在Clojure中是否有用于创建哈希映射的简短表单?

时间:2016-12-08 19:54:32

标签: clojure

是否有允许我执行的简短表单/宏

-(void) reloadCloudDestinations
{
   [self setupCloudLibrary];
   TSCAccount* account = [TSCCloudServices activeAccount];
   if( account.status == TSCAccount_SignedIn )
   {
      dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
      __weak __typeof(self) weakSelf = self;

      @try
      {
         AFHTTPSessionManager *test = (AFHTTPSessionManager*)[(TSCAccountHTTPSession*)[self.libraryCore valueForKey:@"sessionManager"] valueForKey:@"httpClient"];
         NSLog(@"%@", test);
         [self.libraryCore destinationsWithActions:NEVER_TRANSLATE(@"publish,list") completionBlock:^(NSArray *destinations, NSError *error) {

            @try
            {
               if( error == nil )
               {
                  [weakSelf createButtonsForNewDestinationsNotAlreadyPresent:destinations];
               }
               else
               {
                  NSLog(@"destinationsWithBlock error: %@", error);
               }
            }
            @catch (NSException* exception)
            {
               NSLog(@"reloadCloudDestinations - destinationWithBlock completion - An exception was thrown %@", exception);
            }
            @finally
            {
              dispatch_semaphore_signal(semaphore);
            }
         }];

         dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
      }
      @catch (NSException* exception)
      {
         NSLog(@"reloadCloudDestinations - An exception was thrown %@", exception);
         dispatch_semaphore_signal(semaphore);
      }
   }
}

而不是

(defn f [a b c]
  {a b c})

3 个答案:

答案 0 :(得分:1)

这显示了这些步骤。删除println以供实际使用:

(ns clj.core
  (:gen-class))

(defmacro hasher [& args] 
  (let [keywords      (map keyword args)
        values        args
        keyvals-list  (interleave keywords values)
  ]
    (println "keywords     "  keywords)
    (println "values       "  values)
    (println "keyvals-list "  keyvals-list)
    `(hash-map ~@keyvals-list)
  )
)

(def a 1)
(def b 2)
(println \newline "result: " (hasher a b))

> lein run
keywords      (:a :b)
values        (a b)
keyvals-list  (:a a :b b)

result:  {:b 2, :a 1}

答案 1 :(得分:1)

(defmacro as-map [& syms]
  (zipmap (map keyword syms) syms))

用法:

(def a 42)
(def b :foo)

(as-map a b)
;;-> {:a 42 :b :foo}

请注意,要支持命名空间关键字,如果要将其保留为短,则必须放弃对ns别名的支持:

(defmacro as-map [& syms]
  (zipmap (map keyword syms) (map (comp symbol name) syms)))

用法:

(def a 42)
(def b :foo)

(as-map example/a foo-of/b)
;;-> {:example/a 42 :foo-of/b :foo}

建议:可能不是一个好主意,以可读性和表达性以及命名本地绑定的灵活性为代价来节省一些键盘命中率。

答案 2 :(得分:1)

这是我的一个古老的片段,我已经踢了一会儿。

(declare ^:private restructure*)

(defn ^:private restructure-1 [m [e k]]
  (cond
    (= :strs e) (reduce #(assoc %1 (name %2) %2) m k)
    (= :keys e) (reduce #(assoc %1 (keyword (namespace %2) (name %2)) %2) m k) 
    :else       (assoc m k (restructure* e))))

(defn ^:private restructure* [form]
  (if-not (map? form)
    form
    (as-> {} v
      (reduce restructure-1 v form)
      `(hash-map ~@(mapcat identity v)))))

(defmacro restructure [form]
  (restructure* form))

这个想法是它提供了clojure.core / destructure的补充,它从解构形式到绑定,捕获绑定并构建数据结构。

(let [x 1 y 2 z 3]
  (restructure {:keys [x y z]}))
;; => {:x 1 :y 2 :z 3}