2013-09-21 13 views
89

के बराबर इस सवाल का यहाँ के बाद:जावास्क्रिप्ट सी # LINQ का चयन

Using the checked binding in knockout with a list of checkboxes checks all the checkboxes

मुझे लगता है कि एक सरणी से चयन की अनुमति नॉकआउट का उपयोग कर कुछ चेक बॉक्स बना लिया है। बेला पोस्ट के ऊपर से लिया वर्किंग:

http://jsfiddle.net/NsCXJ/

सिर्फ फल के पहचान पत्र की एक सरणी बनाने का एक आसान तरीका है?

मैं और अधिक के साथ सी # घर पर मैं कहाँ selectedFruits.select(fruit=>fruit.id);

की तर्ज पर कुछ करना चाहते हैं वहाँ जावास्क्रिप्ट/jQuery के साथ कुछ ऐसा ही करने के लिए कुछ विधि/तैयार समारोह है कर रहा हूँ? या सबसे सरल विकल्प सूची के माध्यम से लूप करना होगा और दूसरी सरणी बनाना होगा? मैं जेएसओएन में सरणी को सर्वर पर वापस पोस्ट करना चाहता हूं इसलिए भेजा गया डेटा कम करने की कोशिश कर रहा हूं।

उत्तर

146

हां, Array.map() या $.map() वही काम करता है।

//array.map: 
var ids = this.fruits.map(function(v){ 
    return v.Id; 
}); 

//jQuery.map: 
var ids2 = $.map(this.fruits, function (v){ 
    return v.Id; 
}); 

console.log(ids, ids2); 

http://jsfiddle.net/NsCXJ/1/

के बाद से array.map पुराने ब्राउज़र में समर्थित नहीं है, मेरा सुझाव है कि आप jQuery विधि के साथ चिपके रहते हैं।

यदि आप किसी अन्य कारण से दूसरे को पसंद करते हैं तो आप हमेशा पुराने ब्राउजर समर्थन के लिए पॉलीफिल जोड़ सकते हैं।

तुम हमेशा के रूप में अच्छी सरणी प्रोटोटाइप करने के लिए कस्टम तरीकों जोड़ सकते हैं:

Array.prototype.select = function(expr){ 
    var arr = this; 
    //do custom stuff 
    return arr.map(expr); //or $.map(expr); 
}; 

var ids = this.fruits.select(function(v){ 
    return v.Id; 
}); 

समारोह निर्माता का उपयोग करता है अगर आप एक स्ट्रिंग पारित एक विस्तारित संस्करण। कुछ शायद के साथ चारों ओर खेलने के लिए:

Array.prototype.select = function(expr){ 
    var arr = this; 

    switch(typeof expr){ 

     case 'function': 
      return $.map(arr, expr); 
      break; 

     case 'string': 

      try{ 

       var func = new Function(expr.split('.')[0], 
             'return ' + expr + ';'); 
       return $.map(arr, func); 

      }catch(e){ 

       return null; 
      } 

      break; 

     default: 
      throw new ReferenceError('expr not defined or not supported'); 
      break; 
    } 

}; 

console.log(fruits.select('x.Id')); 

http://jsfiddle.net/aL85j/

अद्यतन:

इस के बाद से इस तरह के एक लोकप्रिय जवाब बन गया है, मैं इसी तरह मेरे where() + firstOrDefault() जोड़ रहा। ये भी स्ट्रिंग आधारित समारोह निर्माता दृष्टिकोण के साथ इस्तेमाल किया जा सकता है (जो सबसे तेज है), लेकिन यहाँ एक वस्तु फिल्टर के रूप में शाब्दिक का उपयोग कर एक और तरीका है:

Array.prototype.where = function (filter) { 

    var collection = this; 

    switch(typeof filter) { 

     case 'function': 
      return $.grep(collection, filter); 

     case 'object': 
      for(var property in filter) { 
       if(!filter.hasOwnProperty(property)) 
        continue; // ignore inherited properties 

       collection = $.grep(collection, function (item) { 
        return item[property] === filter[property]; 
       }); 
      } 
      return collection.slice(0); // copy the array 
             // (in case of empty object filter) 

     default: 
      throw new TypeError('func must be either a' + 
       'function or an object of properties and values to filter by'); 
    } 
}; 


Array.prototype.firstOrDefault = function(func){ 
    return this.where(func)[0] || null; 
}; 

उपयोग:

var persons = [{ name: 'foo', age: 1 }, { name: 'bar', age: 2 }]; 

// returns an array with one element: 
var result1 = persons.where({ age: 1, name: 'foo' }); 

// returns the first matching item in the array, or null if no match 
var result2 = persons.firstOrDefault({ age: 1, name: 'foo' }); 

यहाँ एक है फंक्शन कन्स्ट्रक्टर बनाम ऑब्जेक्ट शाब्दिक गति की तुलना करने के लिए jsperf test। यदि आप पूर्व का उपयोग करने का निर्णय लेते हैं, तो तारों को सही ढंग से उद्धृत करने के लिए ध्यान रखें।

मेरी व्यक्तिगत वरीयता 1-2 गुणों को फ़िल्टर करते समय ऑब्जेक्ट शाब्दिक आधारित समाधानों का उपयोग करना है, और अधिक जटिल फ़िल्टरिंग के लिए कॉलबैक फ़ंक्शन पास करना है।

2 सामान्य युक्तियों के साथ इस समाप्त कर देंगे जब देशी वस्तु प्रोटोटाइप के लिए विधियां जोड़ने:

if(!Array.prototype.where) { Array.prototype.where = ...

  • आप हैं: अधिलेखित जैसे पहले मौजूदा तरीकों की घटना के लिए

    1. चेक IE8 और नीचे का समर्थन करने की आवश्यकता नहीं है, उन्हें Object.defineProperty का उपयोग करके विधियों को परिभाषित करने के लिए विधियों को परिभाषित करें। अगर किसी ने किसी सरणी पर for..in का उपयोग किया (जो पहले स्थान पर गलत है) वे भी समृद्ध गुणों को पुन: सक्रिय करेंगे। बिलकुल चौकन्ना।

  • +1

    @ChrisNevill मैंने – Johan

    +0

    @MUlferts को अच्छी पकड़, अपडेट किया गया है, तो एक स्ट्रिंग संस्करण भी जोड़ा है। आजकल मैं इस तरह के कार्यों के लिए lodash का उपयोग करने का सुझाव दूंगा। वे – Johan

    +0

    से ऊपर के कोड के समान इंटरफ़ेस का पर्दाफाश करते हैं, नॉकआउट अवलोकनों का समर्थन करने के लिए: 'वापसी प्रकार आइटम [संपत्ति] ===' फ़ंक्शन '? आइटम [संपत्ति]() === फ़िल्टर [संपत्ति]: आइटम [संपत्ति] === फ़िल्टर [संपत्ति]; ' –

    2

    underscore.js पर एक झांक लें जो कई linq कार्यों को प्रदान करता है। उदाहरण में आप देते हैं कि आप मानचित्र फ़ंक्शन का उपयोग करेंगे।

    +1

    यदि कोई यह जानना चाहता है कि उन्होंने तुलना कैसे की है तो मैंने ब्लॉग पोस्ट किया है जो 15 से अधिक लोकप्रिय LINQ/underscore.js कार्यों के बीच अंतर बताता है: https://www.vladopandzic.com/javascript/comparing-underscore-js-with-linq/ –

    13

    चूंकि आप नॉकआउट का उपयोग कर रहे हैं, तो आपको नॉकआउट यूटिलिटी फ़ंक्शन arrayMap() का उपयोग करने पर विचार करना चाहिए और यह अन्य सरणी उपयोगिता फ़ंक्शन है।

    यहाँ सरणी उपयोगिता कार्यों और उनके समकक्ष LINQ तरीकों की एक सूची है:

    var mapped = ko.utils.arrayMap(selectedFruits, function (fruit) { 
        return fruit.id; 
    }); 
    

    आप में इंटरफ़ेस की तरह एक LINQ चाहते हैं:

    arrayFilter() -> Where() 
    arrayFirst() -> First() 
    arrayForEach() -> (no direct equivalent) 
    arrayGetDistictValues() -> Distinct() 
    arrayIndexOf() -> IndexOf() 
    arrayMap() -> Select() 
    arrayPushAll() -> (no direct equivalent) 
    arrayRemoveItem() -> (no direct equivalent) 
    compareArrays() -> (no direct equivalent) 
    

    तो आप अपने उदाहरण में क्या कर सकते हैं यह है जावास्क्रिप्ट, आप linq.js जैसी लाइब्रेरी का उपयोग कर सकते हैं जो कई LINQ विधियों के लिए एक अच्छा इंटरफ़ेस प्रदान करता है।

    var mapped = Enumerable.From(selectedFruits) 
        .Select("$.id") // 1 of 3 different ways to specify a selector function 
        .ToArray(); 
    
    2

    मैं TsLinq.codeplex.com तहत टाइपप्रति के लिए एक Linq पुस्तकालय है कि आप सादे जावास्क्रिप्ट के लिए भी उपयोग कर सकते हैं का निर्माण किया है। यह लाइब्रेरी Linq.js की तुलना में 2-3 गुना तेज है और इसमें सभी लिंक विधियों के लिए यूनिट परीक्षण शामिल हैं। शायद आप उस की समीक्षा कर सकते हैं।

    29

    मुझे पता है कि यह एक देर का जवाब है लेकिन यह मेरे लिए उपयोगी था! बस $.grep फ़ंक्शन का उपयोग करके पूरा करने के लिए, आप linq where() का अनुकरण कर सकते हैं।

    Linq:

    var maleNames = people 
    .Where(p => p.Sex == "M") 
    .Select(p => p.Name) 
    

    जावास्क्रिप्ट:

    // replace where with $.grep 
    //   select with $.map 
    var maleNames = $.grep(people, function (p) { return p.Sex == 'M'; }) 
          .map(function (p) { return p.Name; }); 
    
    +0

    यही वही है जो मैं चाहता हूं..लेकिन आपके उत्तर और संख्यात्मक के बीच क्या अधिक अच्छा है। (चयनित फ्राइट्स)। चयन करें (फ़ंक्शन (फल) {वापसी fruit.id;}); – Bharat

    0

    Dinqyjs एक LINQ की तरह वाक्यविन्यास है और नक्शे और indexOf जैसे कार्यों के लिए polyfills प्रदान करता है, और जावास्क्रिप्ट में सरणियों के साथ काम करने के लिए विशेष रूप से डिजाइन किया गया है ।

    8

    तुम भी कोशिश कर सकते हैं linq.js

    linq.js में अपने

    selectedFruits.select(fruit=>fruit.id); 
    

    हो जाएगा

    Enumerable.From(selectedFruits).Select(function (fruit) { return fruit.id; }); 
    
    7

    ES6 रास्ता:

    let people = [{firstName:'Alice',lastName:'Cooper'},{firstName:'Bob',age:'Dylan'}]; 
    let names = Array.from(people, p => p.firstName); 
    for (let name of names) { 
        console.log(name); 
    } 
    

    अल इसलिए: https://jsfiddle.net/52dpucey/

    +0

    बहुत सराहना की। मैं सिर्फ ईएस 6 में जा रहा हूं इसलिए यह आसान हो सकता है! –

    संबंधित मुद्दे