4

私は、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 ステートメントを使用してループからすばやく抜け出せるようにする関数を使用しましたが、これは 1 回しか使用されないため、この関数はちょっと厄介です。

それで、できれば新しい関数を作成する必要のない、より短いCSに相当するものはありますか?

4

2 に答える 2

8

これを試すことができます:

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]

しかし、最初のものの方が読みやすいと思います(また、結果の中間配列を生成する必要もありません)。特定のアイテムのすべてのショップを検索したい場合、これはより良いアプローチです。

findShops = (item) ->
  shop for shop, items of shopMap when item in items
于 2012-06-18T19:36:04.370 に答える
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'])

デモ

この実装では、前もって 1 回だけ構造をループする必要があります (さらに、shopMap が変更された場合は更新することもできます)。あなたとエピデミアンの答えでは、この特定のタイプのルックアップを行う必要があるたびにループする必要があります。この操作を何度も行うと、違いが生じる可能性があります。一方、shopMap が非常に大きい場合 (数千のエントリなど)、私の実装はより多くのメモリを消費します。

これをどの程度堅牢にしたいかによっては、それをクラスに変換し、クラスのインターフェースを介して操作を行うことができます。addCategory メソッドと deleteCategory メソッド、および getStoreFromCategory メソッドが必要です。これは基本的に上記で実装しているものです。このオブジェクト指向のアプローチは、内部のデータ構造/実装を非表示にするため、後で実装を変更してメモリまたは速度を最適化できます。

于 2012-06-18T22:31:01.250 に答える