Javascript實現Linq查詢方式

來源:互聯網
上載者:User

Linq是.net平台一個重要的技術,全稱Language Integrated Query。通過構建快速查詢語句,可快速從資料庫或集合中篩選資料集、以查詢資料庫相同的方式操作記憶體資料。

     在ECMAScript 5th以後的版本中,Javascript實現了有限的有限的Linq查詢方式,包括forEach, every, some, filter, map, reduce and reduceRight.      首先需要說明,以上這些方法並不是跨瀏覽器的,對版本有相應的限制。我們知道Linq的對象需要實現Enumerable介面,本篇文章主要介紹使用JS類比實現C# 中的Linq查詢,包括 聚集查詢、迭代查詢、條件查詢、構建Selector查詢器等。 Javascript本質上並不支援類的繼承,通過屬性的繼承可實作類別的物件導向的功能,所以這也被認為是物件導向的一種方式,這就意味著可以使用它的屬性構建更多物件導向的介面。例如Array,它是繼承自Array.prototype 。如果更改了Array.prototype,那麼基於這個屬性繼承的數組必然會變化。有了這些依據後開始構建我們的Linq功能。 舉個例子,JS API不支援union方法,但支援concat方法合并資料。 Array.prototype.union先來看看一個.NET下的簡單查詢方式  var someArray = new int[] { 1, 2, 3, 4 };var otherArray = someArray.Select(t => t * 2);   在C#下使用查詢資料時使用的是Select,使用一個 Delegate 構建查詢。在這個例子中,我們使用了  t => t * 2 是一個 Lambda運算式。 將這個功能嫁接到JS下,定義一個function(){} JS下的Select查詢可以是這樣  var someArray = [1, 2, 3, 4];var otherArray = someArray.select(function (t) { return t * 2 }); 然後定義 比較(EqualityComparer)、排序(SortComparer)、條件(Predicate)、查詢器(Selector)  比較、排序、條件、查詢器  Javascript Linq 查詢器 Select 遍曆元素下的每一個元素,調用JS.Call方法返回資料。  Array.prototype.select = Array.prototype.map || function (selector, context) {    context = context || window;    var arr = [];    var l = this.length;    for (var i = 0; i < l; i++)        arr.push(selector.call(context, this[i], i, this));    return arr;};  var arr = [1, 2, 3, 4, 5];var doubled = arr.select(function(t){ return t * 2 });  SelectMany   SelectMany  Take  Array.prototype.take = function (c) {    return this.slice(0, c);};   var arr = [1, 2, 3, 4, 5]; var res = arr.take(2);Skip 跳過指定數後返回集合資料,使用slice。  Array.prototype.skip = function (c) {    return this.slice(c);};  var arr = [1, 2, 3, 4, 5]; var res = arr.skip(2);  First 返回序列的第一個元素,如果沒有元素,可以指定一個預設元素。  Array.prototype.first = function (predicate, def) {    var l = this.length;    if (!predicate) return l ? this[0] : def == null ? null : def;    for (var i = 0; i < l; i++)        if (predicate(this[i], i, this))            return this[i];    return def == null ? null : def;};  var arr = [1, 2, 3, 4, 5];var t1 = arr.first();  var t2 = arr.first(function(t){ return t > 2 }); var t3 = arr.first(function(t){ return t > 10 }, 10); //預設值是10 Union 合并兩個集合中的資料,使用concat,不合并重複資料。  Array.prototype.union = function (arr) {    return this.concat(arr).distinct();};   var arr1 = [1, 2, 3, 4, 5]; var arr2 = [5, 6, 7, 8, 9];var res = arr1.union(arr2);   Distinct 找出不重複的資料。當有重複元素是只push一個元素進集合。 Array.prototype.distinct = function (comparer) {    var arr = [];    var l = this.length;    for (var i = 0; i < l; i++) {        if (!arr.contains(this[i], comparer))            arr.push(this[i]);    }    return arr;};      var arr1 = [1, 2, 2, 3, 3, 4, 5, 5];   var res1 = arr.distinct();  // [1, 2, 3, 4, 5] var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:1}];var res2 = arr2.distinct(function(a, b){ return a.Val == b.Val }); //返回[{Name:"A", Val:1}]  IndexOf 尋找指定的值第一次出現的位置。 Array.prototype.indexOf = Array.prototype.indexOf || function (o, index) {    var l = this.length;    for (var i = Math.max(Math.min(index, l), 0) || 0; i < l; i++)        if (this[i] === o) return i;    return -1;};   var arr = [1, 2, 3, 4, 5];var index = arr.indexOf(2);  // 1  Remove 從集合中移除指定元素。  Array.prototype.remove = function (item) {    var i = this.indexOf(item);    if (i != -1)        this.splice(i, 1);};  var arr = [1, 2, 3, 4, 5];arr.remove(2);   // [1, 3, 4, 5] OrderBy  Array.prototype.orderBy = function (selector, comparer) {    comparer = comparer || DefaultSortComparer;    var arr = this.slice(0);    var fn = function (a, b) {        return comparer(selector(a), selector(b));    };     arr.thenBy = function (selector, comparer) {        comparer = comparer || DefaultSortComparer;        return arr.orderBy(DefaultSelector, function (a, b) {            var res = fn(a, b);            return res === 0 ? comparer(selector(a), selector(b)) : res;        });    };     arr.thenByDescending = function (selector, comparer) {        comparer = comparer || DefaultSortComparer;        return arr.orderBy(DefaultSelector, function (a, b) {            var res = fn(a, b);            return res === 0 ? -comparer(selector(a), selector(b)) : res;        });    };     return arr.sort(fn);};      var arr = [{Name:"A", Val:1}, {Name:"a", Val:2}, {Name:"B", Val:1}, {Name:"C", Val:2}]; var res1 = arr.orderBy(function(t){ return t.Name });    var res2 = arr.orderBy(function(t){ return t.Name }, function(a, b){    if(a.toUpperCase() > b.toUpperCase()) return 1;    if(a.toUpperCase() < b.toUpperCase()) return -1;    return 0;});     OrderByDescending Array.prototype.orderByDescending = function (selector, comparer) {    comparer = comparer || DefaultSortComparer;    return this.orderBy(selector, function (a, b) { return -comparer(a, b) });}; var arr = [{Name:"A", Val:1}, {Name:"a", Val:2}, {Name:"B", Val:1}, {Name:"C", Val:2}];var res = arr.orderByDescending(function(t){ return t.Name });    GroupBy Array.prototype.groupBy = function (selector, comparer) {    var grp = [];    var l = this.length;    comparer = comparer || DefaultEqualityComparer;    selector = selector || DefaultSelector;     for (var i = 0; i < l; i++) {        var k = selector(this[i]);        var g = grp.first(function (u) { return comparer(u.key, k); });         if (!g) {            g = [];            g.key = k;            grp.push(g);        }         g.push(this[i]);    }    return grp;};     Array.prototype.groupBy = function (selector, comparer) {    var grp = [];    var l = this.length;    comparer = comparer || DefaultEqualityComparer;    selector = selector || DefaultSelector;     for (var i = 0; i < l; i++) {        var k = selector(this[i]);        var g = grp.first(function (u) { return comparer(u.key, k); });         if (!g) {            g = [];            g.key = k;            grp.push(g);        }         g.push(this[i]);    }    return grp;};    Javascript Linq 彙總Min  Array.prototype.min = function (s) {    s = s || DefaultSelector;    var l = this.length;    var min = s(this[0]);    while (l-- > 0)        if (s(this[l]) < min) min = s(this[l]);    return min;};    var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];var min1 = arr.min();  // 1  var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];var min2 = arr2.min(function(t){ return t.Val });   // 1  Max Array.prototype.max = function (s) {    s = s || DefaultSelector;    var l = this.length;    var max = s(this[0]);    while (l-- > 0)        if (s(this[l]) > max) max = s(this[l]);    return max;};   var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];var max1 = arr.max();  // 8  var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];var max2 = arr2.max(function(t){ return t.Val });   // 2   Sum Array.prototype.sum = function (s) {    s = s || DefaultSelector;    var l = this.length;    var sum = 0;    while (l-- > 0) sum += s(this[l]);    return sum;};  var arr1 = [1, 2, 3, 4, 5, 6, 7, 8];var sum1 = arr.sum();  // 36  var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:2}];var sum2 = arr2.sum(function(t){ return t.Val });   // 3   Javascript Linq 條件查詢Where Array.prototype.where = Array.prototype.filter || function (predicate, context) {    context = context || window;    var arr = [];    var l = this.length;    for (var i = 0; i < l; i++)        if (predicate.call(context, this[i], i, this) === true) arr.push(this[i]);    return arr;};  var arr = [1, 2, 3, 4, 5];var res = arr.where(function(t){ return t > 2 }) ;  // [3, 4, 5]  Any  Array.prototype.any = function (predicate, context) {    context = context || window;    var f = this.some || function (p, c) {        var l = this.length;        if (!p) return l > 0;        while (l-- > 0)            if (p.call(c, this[l], l, this) === true) return true;        return false;    };    return f.apply(this, [predicate, context]);};    var arr = [1, 2, 3, 4, 5];var res1 = arr.any();  // truevar res2 = arr.any(function(t){ return t > 5 });  // false  All  Array.prototype.all = function (predicate, context) {    context = context || window;    predicate = predicate || DefaultPredicate;    var f = this.every || function (p, c) {        return this.length == this.where(p, c).length;    };    return f.apply(this, [predicate, context]);};   var arr = [1, 2, 3, 4, 5];var res = arr.all(function(t){ return t < 6 });  // true  Contains  Array.prototype.contains = function (o, comparer) {    comparer = comparer || DefaultEqualityComparer;    var l = this.length;    while (l-- > 0)        if (comparer(this[l], o) === true) return true;    return false;};  var arr1 = [1, 2, 3, 4, 5]; var res1 = arr.contains(2);  // true  var arr2 = [{Name:"A", Val:1}, {Name:"B", Val:1}]; var res2 = arr2.contains({Name:"C", Val:1}, function(a, b){ return a.Val == b.Val }) ;  // true   Javasciprt Linq 迭代ForEach   Array.prototype.forEach = Array.prototype.forEach || function (callback, context) {    context = context || window;    var l = this.length;    for (var i = 0; i < l; i++)        callback.call(context, this[i], i, this);};   var arr = [1, 2, 3, 4, 5];arr.forEach(function(t){ if(t % 2 ==0) console.log(t); });     DefaultIfEmpty  Array.prototype.defaultIfEmpty = function (val) {    return this.length == 0 ? [val == null ? null : val] : this;};   var arr = [1, 2, 3, 4, 5];var res = arr.where(function(t){ return t > 5 }).defaultIfEmpty(5);  // [5]  
相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。