<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      【開源】Qone 正式發布,使 javascript 支持 .NET LINQ

      2018-04-24 14:59  【當耐特】  閱讀(6904)  評論(19)    收藏  舉報

      Qone

      下一代 Web 查詢語言,使 javascript 支持 LINQ

      Github: https://github.com/dntzhang/qone

      緣由

      最近剛好修改了騰訊文檔 Excel 表格公式的一些 bug,主要是修改公式的 parser 。比如下面的腳本怎么轉成 javascript 運行?

      = IF(SUM(J6:J7) + SUM(J6:J7) > 10, "A2 是 foo", "A2 不是 foo")
      

      公式或一些腳本語言的實現包含幾個主要步驟:

      scanner > lexer > parser > ast > code string
      

      得到 code string 之后可以動態運行,比如 js 里使用 eval ,eval 能保留上下文信息,缺點是執行代碼包含編譯器代碼,eval 的安全性等。
      得到 code string 之后也可直接使用生成的 code string 運行,缺點是依賴構建工具或者編輯器插件去動態替換源代碼。

      比如 wind 同時支持 JIT 和 AOT, qone 的思路和上面類似,但不完全相同, qone 的如下:

      scanner > lexer > parser > ast > method(ast)
      

      這個后面寫原理時候再細說。

      總的來說,因為騰訊文檔公式相關工作、早年的 kmdjs 開發 (uglify2) 和 .NET 開發,所以有了 qone 。


      LINQ

      LINQ (語言集成查詢) 是 .NET Framework 3.5 版中引入的一項創新功能。在 Visual Studio 中,可以用 Visual Basic 或 C# 為以下數據源編寫 LINQ 查詢:SQL Server 數據庫、XML 文檔、ADO.NET 數據集,以及可枚舉的 Objects(即 LINQ to Objects)。

      qone 是一款讓 Web 前端工程師在 javascript 使用 .NET 平臺下類似 LINQ 語法的前端庫。qone 讓 Web 前端工程師通過字符串的形式實現了 LINQ to Objects 的調用(下面統一叫做 qone to objects),Objects即 JSON 組成的 Array。舉個簡單的例子(qone 遠比下面的例子強大):

      var list = [
          { name: 'qone', age: 1 },
          { name: 'linq', age: 18 },
          { name: 'dntzhang', age: 28 }
      ]
      
      var result = qone({ list }).query(`
                  from n in list   
                  where n.age > 18
                  select n
              `)
      
      assert.deepEqual(result, [{ "name": "dntzhang", "age": 28 }])
      

      與 LINQ 一樣,和 SQL 不同,qone 的 from 也在前面,為后面語句能夠有智能提示,qone 是基于 string 的實時編譯,不是 javasript 的原生語法,所以雖然 from 寫在前面但不支持智能提示,但可以專門為 qone 寫個編輯器插件去實現智能提示,所以 qone 語法設計上依然把 from 放在前面。

      從根本上說,qone to objects 表示一種新的處理集合的方法。 采用舊方法,您必須編寫指定如何從集合檢索數據的復雜的 foreach 循環。 而采用 qone 方法,您只需編寫描述要檢索的內容的聲明性代碼。
      另外,與傳統的 foreach 循環相比,qone 查詢具有三大優勢:

      • 它們更簡明、更易讀,尤其在篩選多個條件時
      • 它們使用最少的應用程序代碼提供強大的篩選、排序和分組功能
      • 無需修改或只需做很小的修改即可將它們移植到其他數據源

      通常,您要對數據執行的操作越復雜,就越能體會到 qone 相較于傳統迭代技術的優勢。

      qone 安裝

      npm install qone
      

      qone 關鍵字與運算符

      • from
      • in
      • where
      • select
      • orderby
      • desc
      • asc
      • groupby
      • limit

      其中 from 和 in 一起使用,orderby 和 desc 或者 asc 一起使用。

      from 也可以把子屬性作為 dataSource:

      from n in data.list   
      

      qone 支持下面三類運算符:

      • 括號:( )
      • 比較運算符: = , > , < , >= , <= , !=
      • 與或非: && , || , !

      條件判斷語句也支持 null, undefined, true, false。

      通過上面各種組合,你可以寫出很復雜的查詢條件。比如:

      qone({ list }).query(`
          from n in list   
          where !(n.age > 17 || n.age < 2) && n.name != 'dntzhang'
          select n
      `)
      

      也支持 bool 類型的查詢:

      var list = [
          { name: 'qone', age: 1, isBaby: true },
          { name: 'linq', age: 18 },
          { name: 'dntzhang', age: 28 }]
      
      var result = qone({ list }).query(`
              from a in list       
              where a.isBaby && n.name = 'qone'
              select a
          `)
      
      assert.deepEqual(result, [{ name: 'qone', age: 1, isBaby: true }])
      

      其中 isBaby 是 bool 類型,同樣的寫法:
      a.isBaby = true (等同于: a.isBaby)
      a.isBaby = false (等同于: !a.isBaby)

      qone 方法注入

      通過上面介紹發現 qone 不支持加減乘除位求模運算?怎么才能圖靈完備?方法注入搞定一切!如下所示:

      QUnit.test("Method test 8", function (assert) {
          var arr = [1, 2, 3, 4, 5]
      
          qone('square', function (num) {
              return num * num
          })
      
          qone('sqrt', function (num) {
              return Math.sqrt(num)
          })
      
          var result = qone({ arr }).query(`
            from n in arr   
            where  sqrt(n) >= 2 
            select { squareValue : square(n) }
        `)
      
          assert.deepEqual(result, [{ "squareValue": 16 }, { "squareValue": 25 }])
      })
      

      方法也是支持多參數傳入,所以可以寫出任意的查詢條件。其中select, where, orderby, groupby 語句都支持方法注入。

      qone select 輸出

      通過 select 可以輸出各種格式和字段的數據:

      QUnit.test("Select JSON test", function (assert) {
          var list = [
              { name: 'qone', age: 1 },
              { name: 'linq', age: 18 },
              { name: 'dntzhang', age: 28 }
          ]
      
          var result = qone({ list }).query(`
                      from n in list   
                      where n.age < 20
                      select {n.age, n.name}
                  `)
      
          assert.deepEqual(result, [
              { "age": 1 , "name": "qone" },
              { "age": 18, "name": "linq" }
          ])
      
      })
      

      把所有場景列舉一下:

      • select n 輸出源 item
      • select n.name 輸出一維表
      • select n.name, n.age 輸出二維表
      • select { n.age, n.name } 缺省方式輸出 JSON Array(key自動使用 age 和 name)
      • select { a: n.age, b: n.name } 指定 key 輸出 JSON Array
      • select { a: methodName(n.age), b: n.name } 注入方法
      • select methodName(n.age), n.name 注入方法
      • select methodName(n.age, n.name, 1, true, 'abc') 注入方法并傳遞參數

      qone orderby

      var result = qone({ list }).query(`
                      from n in list   
                      where n.age > 0
                      orderby n.age asc, n.name desc
                      select n
                  `)
      
      

      如果沒有標記 asc 或者 desc,使用默認排序 asc。

      qone groupby

      QUnit.test("Simple groupby test 1", function (assert) {
          var list = [
              { name: 'qone', age: 1 },
              { name: 'linq', age: 18 },
              { name: 'dntzhang1', age: 28 },
              { name: 'dntzhang2', age: 28 },
              { name: 'dntzhang3', age: 29 }
          ]
      
          var result = qone({ list }).query(`
                      from n in list   
                      where n.age > 18
                      groupby n.age
                  `)
      
          assert.deepEqual(result, [
              [{ "name": "dntzhang1", "age": 28 }, { "name": "dntzhang2", "age": 28 }],
              [{ "name": "dntzhang3", "age": 29 }]])
      
      })
      

      groupby 可以作為結束語句,不用跟著也不能跟著 select 語句,groupby 也可以支持方法注入。

      qone 多數據源

      QUnit.test("Multi datasource with props condition", function (assert) {
      
          var listA = [
              { name: 'qone', age: 1 },
              { name: 'linq', age: 18 },
              { name: 'dntzhang', age: 28 }]
      
      
          var listB = [
              { name: 'x', age: 11 },
              { name: 'xx', age: 18 },
              { name: 'xxx', age: 13 }
          ]
      
          var result = qone({ listA, listB }).query(`
                  from a in listA     
                  from b in listB      
                  where a.age = b.age
                  select a, b
              `)
      
          assert.deepEqual(result, [[{ "name": "linq", "age": 18 }, { "name": "xx", "age": 18 }]])
      })
      

      多數據源會產生笛卡兒積。

      qone 嵌套子數據源

      QUnit.test("Multi deep from test ", function (assert) {
      
          var list = [
              { name: 'qone', age: 1, isBaby: true, colors: [{ xx: [1, 2, 3] }, { xx: [11, 2, 3] }] },
              { name: 'linq', age: 18, colors: [{ xx: [100, 2, 3] }, { xx: [11, 2, 3] }] },
              { name: 'dntzhang', age: 28, colors: [{ xx: [1, 2, 3] }, { xx: [11, 2, 3] }] }]
      
          var result = qone({ list }).query(`
                  from a in list   
                  from c in a.colors   
                  from d in c.xx  
                  where d === 100
                  select a.name, c,d
              `)
      
          assert.deepEqual(result, [["linq", { "xx": [100, 2, 3] }, 100]])
      })
      

      也可以和自身的數據源會產生笛卡兒積。

      qone limit 與分頁查詢

      通過 limit 可以應付最常見的兩種查詢場景 - top N 和 分頁。

      查詢top3:

      QUnit.test("Limit top 3", function (assert) {
          var list = [
              { name: 'dntzhang1', age: 1 },
              { name: 'dntzhang2', age: 2 },
              { name: 'dntzhang3', age: 3 },
              { name: 'dntzhang4', age: 4 },
              { name: 'dntzhang5', age: 5 },
              { name: 'dntzhang6', age: 6 },
              { name: 'dntzhang7', age: 7 },
              { name: 'dntzhang8', age: 8 },
              { name: 'dntzhang9', age: 9 },
              { name: 'dntzhang10', age: 10 }
          ]
      
          var pageIndex = 1,
              pageSize = 4
          var result = qone({ list }).query(`
                          from n in list   
                          select n
                          limit 0, 3
                      `)
      
      
          assert.deepEqual(result, [
      
              { name: 'dntzhang1', age: 1 },
              { name: 'dntzhang2', age: 2 },
              { name: 'dntzhang3', age: 3 }
          ])
      
      })
      

      分頁查詢:

      QUnit.test("Limit one page test", function (assert) {
          var list = [
              { name: 'dntzhang1', age: 1 },
              { name: 'dntzhang2', age: 2 },
              { name: 'dntzhang3', age: 3 },
              { name: 'dntzhang4', age: 4 },
              { name: 'dntzhang5', age: 5 },
              { name: 'dntzhang6', age: 6 },
              { name: 'dntzhang7', age: 7 },
              { name: 'dntzhang8', age: 8 },
              { name: 'dntzhang9', age: 9 },
              { name: 'dntzhang10', age: 10 }
          ]
      
          var pageIndex = 1,
              pageSize = 4
          var result = qone({ list }).query(`
                          from n in list   
                          where n.age > 0
                          select n
                          limit ${pageIndex * pageSize}, ${pageSize}
                      `)
      
      
          assert.deepEqual(result, [
          { name: 'dntzhang5', age: 5 },
          { name: 'dntzhang6', age: 6 },
          { name: 'dntzhang7', age: 7 },
          { name: 'dntzhang8', age: 8 }])
      
      })
      

      star & fork & pr & repl & follow me

      主站蜘蛛池模板: 国产精品亚洲二区在线播放| 99精品国产在热久久无| 亚洲国产福利成人一区二区| 亚洲va韩国va欧美va| 国产欧美精品一区二区三区-老狼| 日本极品少妇videossexhd| 日韩人妻精品中文字幕| 日本无遮挡吸乳呻吟视频| 国产精品久久一区二区三区| 亚洲欧洲日产国产 最新| 日韩精品中文字幕人妻| 国产精久久一区二区三区| 日日猛噜噜狠狠扒开双腿小说| 亚洲国产成人无码影片在线播放| 99热精国产这里只有精品| 亚洲色偷拍区另类无码专区| 日韩精品中文字一区二区| 熟女视频一区二区三区嫩草| 国产va免费精品观看| 午夜DY888国产精品影院| 国产亚洲999精品aa片在线爽| 亚洲国产成人综合自在线| 免费午夜无码片在线观看影院| 亚洲日韩性欧美中文字幕| 日韩精品一区二区三区蜜臀| 奇米四色7777中文字幕| 中文字幕日韩精品亚洲一区| A毛片终身免费观看网站| 精品 无码 国产观看| 高清无码爆乳潮喷在线观看| 黑人巨茎大战欧美白妇| 九九热精品在线视频观看| 九九热在线视频免费播放| 免费乱理伦片在线观看| 深夜av免费在线观看| 久久久久青草线蕉亚洲| 精品国产线拍大陆久久尤物| 视频一区二区不中文字幕| 国精偷拍一区二区三区| 人妻无码中文字幕| 激情在线网|