【问题标题】:List/Object searching in CoffeeScriptCoffeeScript 中的列表/对象搜索
【发布时间】:2012-06-20 19:29:58
【问题描述】:

我正在尝试尽可能高效地使用 CoffeeScript 推导式。我想我已经完成了基本的映射——将一个列表变成另一个列表——但搜索对我来说仍然很冗长。

假设我有一张商品到商店的地图:

shopMap:
  toyStore: ["games", "puzzles"]
  bookStore: ["novels", "picture books"]

并且,给定一件商品,我想知道它在哪家商店。在 CoffeeScript 中最好的方法是什么?

以下是我在 JavaScript 中的表现:

var shop = findShop(item);

function findShop(item) {
   for (shop in shopMap)
      itemList = shopMap[shop]
      for (i = 0, ii = itemList.length; i<ii; i++) {
         if (itemList[i] === item) {
            return shop;
         }
      }
  }
}

我使用了一个函数来让它通过 return 语句快速跳出循环,而不是使用中断,但是这个函数有点丑陋,因为它只被使用一次。

那么有没有更短的 CS 等价物,最好是不需要创建新函数的?

【问题讨论】:

    标签: coffeescript list-comprehension


    【解决方案1】:

    如果这是一个常见的操作,您最好先创建一个中间数据结构并直接进行查找。

    shopMap =
      toyStore: ["games", "puzzles"]
      bookStore: ["novels", "picture books"]
    
    categoryMap = {}
    for k, v of shopMap
      for category in v
        categoryMap[category] = k
    
    alert(categoryMap['puzzles'])
    

    Demo

    使用此实现,您只需预先循环一次结构(如果 shopMap 发生更改,还可能更新它)。使用您和流行病的答案,每次需要进行这种特定类型的查找时,您都必须循环。如果您经常执行此操作,可能会有所作为。另一方面,如果您的 shopMap 非常大(例如数千个条目),那么我的实现将占用更多内存。

    根据您想要使其变得多么健壮,您可能希望将其变成一个类,并通过类的接口对其进行任何操作。您需要 addCategory 和 deleteCategory 方法以及 getStoreFromCategory 方法,这基本上就是我们在上面实现的。这种面向对象的方法将隐藏内部数据结构/实现,以便您以后可以更改实现以优化内存或速度。

    【讨论】:

    • 这是一个很好的解决方案,因为查找成本降低到仅访问属性。但应该注意的是,第一次实现可能是过早优化的情况,至少没有更多信息,它可能会在以后咬住(例如,我们不知道shopMap 是否可以改变,并且在这种情况下,categoryMap 也应该更新)。我会说最好先进行一个简单的实现,并且只有在性能很差并且在分析之后发现商店查找是性能拖累的情况下,才可以实现这样的解决方案:)
    • 谢谢。是的,这可能是现阶段过早的优化,如果我发现我重复使用该操作,我会记住它。谢谢。
    • 是的,我倾向于构建大型 CoffeeScript 库和应用程序,因此我有一种非常面向对象的思维方式。我的第一种方法是将实现隐藏在 Class 接口后面,我可能首先使用 Epidemia 的实现。从 Class 开始的优点是,如果您稍后优化实现,您的客户端代码不需要更改。当然,首先将它放在一个类中可能会过度设计,具体取决于您的情况。
    【解决方案2】:

    你可以试试this:

    findShop = (item) ->
      for shop, items of shopMap
        return shop if item in items
    

    如果你真的想尝试使用列表推导,这是等效的:

    findShop = (item) ->
      (shop for shop, items of shopMap when item in items)[0]
    

    但我认为第一个读起来更好(也不需要为结果生成中间数组)。如果您想为给定项目find all shops,这将是 IMO 更好的方法:

    findShops = (item) ->
      shop for shop, items of shopMap when item in items
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-01
      • 2011-07-08
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 2019-01-14
      相关资源
      最近更新 更多