Skip to content

Instantly share code, notes, and snippets.

@ptaoussanis
Created May 4, 2014 10:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ptaoussanis/6db858a679cff690be8d to your computer and use it in GitHub Desktop.
Save ptaoussanis/6db858a679cff690be8d to your computer and use it in GitHub Desktop.
Alternative `loc-tree` strategy
(def ^:private loc-tree
(let [loc-tree*
(memoize
(fn [loc & [unpadded?]]
(let [loc-parts (str/split (-> loc locale-key name) #"[-_]")
loc-tree (mapv #(keyword (str/join "-" %))
(take-while identity (iterate butlast loc-parts)))
loc-tree-padded (into (vec (repeat (- 3 (count loc-tree)) nil))
loc-tree)]
(if unpadded? loc-tree loc-tree-padded))))]
(identity ; memoize ; Also used runtime by translation fns
(fn [loc-or-locs]
(if-not (vector? loc-or-locs)
(loc-tree* loc-or-locs :unpadded) ; Build search tree from single locale
(->> loc-or-locs ; Build search tree from multiple desc-preference locales
(mapv loc-tree*)
(apply encore/interleave-all)
(filterv identity)
(encore/distinctv)))))))
(comment
(loc-tree :en-US) ; [:en-US :en]
(loc-tree [:en-US]) ; [:en-US :en]
(loc-tree [:en-GB :en-US]) ; [:en-GB :en-US :en]
(loc-tree [:en-GB :en :en-US]) ; [:en-GB :en-US :en]
(loc-tree [:en-GB :fr-FR :en-US]) ; [:en-GB :fr-FR :en-US :en :fr]
(loc-tree [:en-US :fr-FR :fr :en :DE-de]) ; [:en-US :fr-FR :de-DE :en :fr :de]
(time (dotimes [_ 10000] (loc-tree [:en-US :fr-FR :fr :en :DE-de]))))
@ptaoussanis
Copy link
Author

(def ^:private loc-tree
  (let [loc-tree*
        (memoize
          (fn [loc & [unpadded?]]
            (let [loc-parts (str/split (-> loc locale-key name) #"[-_]")
                  loc-tree  (mapv #(keyword (str/join "-" %))
                              (take-while identity (iterate butlast loc-parts)))
                  loc-tree-padded (into (vec (repeat (- 3 (count loc-tree)) nil))
                                    loc-tree)]
              (if unpadded? loc-tree loc-tree-padded))))
        loc-primary* (memoize (fn [loc] (peek (loc-tree* loc))))]
    (encore/memoize* 80000 nil ; Also used runtime by translation fns
      (fn [loc-or-locs]
        (if-not (vector? loc-or-locs)
          (loc-tree* loc-or-locs :unpadded) ; Build search tree from single locale
          ;; Build search tree from multiple desc-preference locales:
          (let [primary-locs (->> loc-or-locs (mapv loc-primary*) (encore/distinctv))
                primary-locs-sort (zipmap primary-locs (range))]
            (->> loc-or-locs
                 (mapv loc-tree*)
                 (apply encore/interleave-all)
                 (filterv identity)
                 (encore/distinctv)
                 (sort-by #(primary-locs-sort (loc-primary* %) 0))
                 (vec))))))))

(comment
  (loc-tree :en-US)   ; [:en-US :en]
  (loc-tree [:en-US]) ; [:en-US :en]
  (loc-tree [:en-GB :en-US])     ; [:en-GB :en-US :en]
  (loc-tree [:en-GB :en :en-US]) ; [:en-GB :en-US :en]
  (loc-tree [:en-GB :fr-FR :en-US]) ; [:en-GB :en-US :en :fr-FR :fr]
  (loc-tree [:en-US :fr-FR :fr :en :DE-de]) ; [:en-US :en :fr-FR :fr :de-DE :de]
  (time (dotimes [_ 10000] (loc-tree [:en-US :fr-FR :fr :en :DE-de]))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment