2017-05-22 9 views
1

私はガンを初めて使っています。私はパターンに基づいてオブジェクトの配列を非常に効果的に減らす既存のコードを持っています。私はGunのマップのコンテキストで実行するためにこれを微調整し、不一致のために未定義に戻すべきだと思っています。私は2つの引数も提供しなければならないと思います。そのうちの1つはwhere節であり、もう1つは返されたオブジェクトに表示されるプロパティです。私はまた、もし私が将来のマッチを使用すると、自動的に吐き出されるだろうと推測しています!私は正しい道にいますか?マップを使ってガンを減らす

const match = (object,key,value) => { 
    const type = typeof(value); 
    if(value && type==="object") { 
    return Object.keys(value).every(childkey => 
      match(object[key],childkey,value[childkey])); 
    if(type==="function") return value(object[key]); 
    return object[key]===value; 
} 
const reduce = (objects,where) => { 
    const keys = Object.keys(where); 
    return objects.reduce((accumulator,current) => { 
    if(keys.every(key => match(current,key,where[key]))) { 
     accumulator.push(current); 
    } 
    return accumulator; 
    },[]); 
} 

let rows = reduce([{name: "Joe",address:{city: "Seattle"},age:25}, 
    {name: "Mary",address:{city: "Seattle"},age:16}, 
    {name: "Joe",address:{city: "New York"},age:20}], 
    {name:() => true, 
    address: {city: "Seattle"}, 
    age: (age) => age > 10}); 

// で結果[{名: "ジョー"、アドレス:{都市: "シアトル"}、年齢:25}、{ 名: "メリー"、アドレス:{都市:「シアトル"}、年齢:16}]

これをさらに調べることで、以下のコードが作成されました。これは書式的には異なりますが、ガンの即応性の性質に準拠しています。しかし、ネストされたオブジェクトをどのように処理するかは不明です。以下のコードはプリミティブでのみ機能します。

const match = (object,key,value) => { 
    const type = typeof(value); 
    if(!object || typeof(object)!=="object") return false; 
    if(value && type==="object") { 
     const child = gun.get(object[key]["#"]); 
     for(let key in value) { 
      const value = {}; 
      child.get(key).val(v => value[key] = v,{wait:0}); 
      if(!match(value,key,value[key])) return; 
     } 
    } 
    if(type==="function") return value(object[key]); 
    return object[key]===value; 
} 

const gun = Gun(["http://localhost:8080/gun"]), 
     users = [{name: "Joe",address:{city: "Seattle"},age:25}, 
     {address:{city: "Seattle"},age:25}, 
     {name: "Mary",address:{city: "Seattle"},age:16}, 
     {name: "Joe",address:{city: "New York"},age:20}]; 

//gun.get("users").map().put(null); 

for(let user of users) { 
    const object = gun.get(user.name).put(user); 
    gun.get("users").set(object); 
} 

gun.get("users").map(user => { 
    const pattern = {name: (value) => value!=null, age: (age) => age > 20}; //, address: {city: "Seattle"} 
    for(let key in pattern) { 
     if(!match(user,key,pattern[key])) return; 
    } 
    return user; 
}).on(data => console.log(data)); 

答えて

0

はい。ガンの.mapmethodはそれ以上のことをします。

var users = gun.get('users')と言ってください。我々は行うことができます。

  • users.map()forEachのようなコールバック機能して、デフォルトのコールバックは、そのままデータを返すことですので。コールバックと
  • users.map(user => user.age * 2)、それはあなたがあなたのようなデータがある場合を除き、mapから期待変換することができます:あなたはundefinedを返す場合、それはそのレコードをfilterます
  • users.map(function(){ return })

警告:現在の時点では、.map(transform)機能は現在実験的であり、それにバグがあり、私。ぜひ試してみてください。

今、私たちはいくつかのクールな振る舞いを取得するには、いくつかの他の方法とそれを組み合わせることができます。

  • users.map().on(cb)は、それらがテーブルに追加されているように、現在および将来のユーザーを取得し、それぞれについての更新を通知しますそのユーザーの
  • users.map().val(cb)は、現在のユーザーと将来のユーザーがテーブルに追加されるときに取得されますが、各ユーザーは1回だけ取得されます。
  • users.val().map().on(cb)は、現在のユーザーのみを取得します(将来ではありません)が、これらのユーザーに更新を取得します。
  • users.val().map().val(cb)は、現在のユーザーのみを取得し(未来ではない)、1回のみ取得します。

はい、あなたは正しい方向にあります。例えば、私がこれを行うの銃のコアでのテストがあります。

list.map(user => user.age === 27? user.name + "thezombie" : u).on(function(data){ 
    // verify 
}); 
list.set({name: 'alice', age: 27}); 
list.set({name: 'bob', age: 27}); 
list.set({name: 'carl', age: 29}); 
list.set({name: 'dave', age: 25}); 

をこれは結果をフィルタリングし、ローカル(表示のみ)データを変換し、ライブmapを作成します

今後、SQLとMongoDB Mangoのクエリ拡張が銃でどのように機能するかについて説明します。

注:GUNはオブジェクト/ノードで要求したプロパティーのみをロードするため、帯域幅は効率的です。 users.map().get('age')を実行すると、すべてのユーザーの年齢値のみがロードされます。

したがって、内部的には効率的なチェックを行うことができます。すべての条件が一致する場合は、オブジェクト全体のみをロードします。さらに、次の2つのオプションがあります。(1)メモリ内のバージョンのガンを使用してサーバー側の要求/応答パターンを作成することができるため、効率的なサーバー側のフィルタリング/クエリが可能です。 (2)アダプタの開発者になってシンプルなワイヤ仕様を学んで、独自のカスタムクエリ言語拡張を書くならば!

他に何かありますか?私を打つ!答えに満足している以上。

編集:コメント欄で私の回答、コメントは明らかにコードを持つことができません。ここでは、より複雑なクエリを "ビルド"する方法の擬似コードを示します。これは、SQL/Mangoクエリ拡張がどのように機能するかに似ています。

mutli-value &ネストされた値のマッチングは、ベースは、しかし、はい、あなたは正しいです、我々はSQL /マンゴーのクエリの例を持っているまで、単純/即時の "アウトオブザボックス"の例はありません。これは、擬似コードであるが、全体にアイデアを得る必要があります。

`` `

Gun.chain.match = function(query, cb){ 
    var gun = this; 
    var fields = Object.keys(query); 
    var check = {}; 
    fields.forEach(function(field){ 
    check[field] = true; 
    gun.get(field).val(function(val){ 
     if(val !== query[field]){ return } 
     check[field] = false; 
     //all checks done? 
     cb(results) 
    }); 
    }); 
    return gun; 
} 

` ``

+0

パターンを使ってフィルタリングするマップを作成したことは、プリミティブ値の場合はかなり簡単です。挑戦はネストされたオブジェクトと一致するようです。 – AnyWhichWay

+0

mutli-valueとネストされた値のマッチングは、これからベースとして "構築"することができますが、SQL/Mangoのクエリの例が出るまで、そうです。単純な/即時の "out of the box"例。これは、擬似コードであるが、全体のアイデアを取得する必要があります '' ' Gun.chain.match =機能(クエリ、CB)を{ VARガン=この; var fields = Object.keys(query); var check = {}; fields.forEach(function(field){ check [field] = true; gun.get(フィールド).val(関数(val){ if(val!== query [field]){return} check [フィールド] = FALSE; は//すべてのチェックが行わCB() }); })。 } '' ' – marknadal

0

ソリューション、トリックはmapを使用することではなくval

Gun.chain.match = function(pattern,cb) { 
      let node = this, 
       passed = true, 
       keys = Object.keys(pattern); 
      keys.every(key => { 
       const test = pattern[key], 
        type = typeof(test); 
       if(test && type==="object") { 
        node.get(key).match(test); 
       } else if(type==="function") { 
        node.get(key).map(value => { 
         if(test(value[key])) { 
          return value; 
         } else { 
          passed = false; 
         } 
        }); 
       } else { 
        node.get(key).map(value => { 
         if(value[key]===test) { 
          return value; 
         } else { 
          passed = false; 
         } 
        }); 
       } 
       return passed; 
      }); 
      if(passed && cb) this.val(value => cb(value)) 
      return this; 
     } 
     const gun = new Gun(); 
     gun.get("Joe").put({name:"Joe",address:{city:"Seattle"},age:20}); 
     gun.get("Joe").match({age: value => value > 15,address:{ city: "Seattle"}},value => console.log("cb1",value)); 
関連する問題