我正试图尽可能高效地使用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等价物,最好不需要创建新函数?
答案 0 :(得分:7)
您可以尝试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
答案 1 :(得分: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'])
使用此实现,您只需要预先在结构中循环一次(如果shopMap更改,可能需要更新它)。有了你和流行病的回答,你必须在每次需要进行这种特殊类型的查找时循环。如果你经常做这个操作,它可能会有所作为。另一方面,如果你的shopMap非常大(比如成千上万的条目),那么我的实现会占用更多的内存。
根据您想要的强大程度,您可能希望将其转换为Class,并通过Class'接口对其进行任何操作。您需要addCategory和deleteCategory方法以及getStoreFromCategory方法,这实际上就是我们在上面实现的方法。这种面向对象的方法会隐藏内部数据结构/实现,因此您可以在以后更改实现以优化内存或速度。