जावास्क्रिप्ट C # LINQ सेलेक्ट करें


137

इस सवाल के बाद यहाँ:

चेकबॉक्स की सूची के साथ नॉकआउट में चेक बाइंडिंग का उपयोग करके सभी चेकबॉक्स की जांच करता है

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

http://jsfiddle.net/NsCXJ/

वहाँ सिर्फ फलों की आईडी की एक सरणी बनाने का एक आसान तरीका है?

मैं C # के साथ घर पर अधिक हूं जहां मैं कुछ की तर्ज पर कुछ करूंगा selectedFruits.select(fruit=>fruit.id);

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

जवाबों:


227

हाँ, 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 परीक्षण है। यदि आप पूर्व का उपयोग करने का निर्णय लेते हैं, तो तार को सही ढंग से उद्धृत करने का ध्यान रखें।

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

मूल ऑब्जेक्ट प्रोटोटाइप में विधियाँ जोड़ने पर मैं इसे 2 सामान्य युक्तियों के साथ समाप्त करूँगा:

  1. ओवरराइटिंग से पहले मौजूदा तरीकों की घटना के लिए जाँच करें:

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

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


1
@ क्रिसहैविल मैंने एक स्ट्रिंग संस्करण जोड़ा है, साथ ही साथ आप अंतर्विरोधित भी हैं
जोहान

@MUlferts अच्छा पकड़, अद्यतन :)। आजकल मैं इस प्रकार के कार्यों के लिए लॉश का उपयोग करने का सुझाव दूंगा। वे कोड के समान इंटरफ़ेस को उजागर करते हैं
जोहान

नॉकआउट वेधशालाओं का समर्थन करने के लिए:return typeof item[property] === 'function' ? item[property]() === filter[property] : item[property] === filter[property];
लिनस कैल्डवेल

@LinusCaldwell जब से मैंने नॉकआउट का उपयोग किया है, तब तक यह एक लंबा समय है, लेकिन कुछ ऐसा क्या है return ko.unwrap(item[property]) === filter[property]?
जोहान

खैर, मैंने नॉकआउट का उल्लेख किया है, लेकिन निश्चित रूप से यह उन सभी गुणों को कवर करेगा जो आवश्यक मापदंडों के बिना कार्य करते हैं। इसके अलावा, कोई आपके सुंदर कोड की सामान्य शैली को क्यों तोड़ेगा?
लिनस कैल्डवेल

33

मुझे पता है कि यह एक देर से जवाब है लेकिन यह मेरे लिए उपयोगी था! बस पूरा करने के लिए, $.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; });

यही मैं चाहता हूँ..लेकिन आपके उत्तर और Enumerable.From (चयनित फ़ॉर्म्स) के बीच में और क्या अच्छा है। चयन (फ़ंक्शन (फल) {return fruit.id;});
भारत

15

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

यहाँ सरणी उपयोगिता फ़ंक्शंस और उनके समतुल्य 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)

तो आप अपने उदाहरण में क्या कर सकते हैं:

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

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

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

14

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/


बहुत सराहना की। मैं बस ES6 में आ रहा हूँ ताकि यह काम आ सके!
क्रिस नेविल


4

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


2

अंडरस्कोर.जेएस पर एक नज़र डालें जो कई लाइनक जैसे फ़ंक्शन प्रदान करता है। आपके द्वारा दिए गए उदाहरण में आप मानचित्र फ़ंक्शन का उपयोग करेंगे।


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

1

आप manipulaपैकेज की कोशिश कर सकते हैं , जो C # LINQ विधियों को लागू करते हैं और इसके सिंटैक्स को सहेजते हैं: https://github.com/litichevskiydv/manipula

https://www.npmjs.com/package/manipula

आपके उदाहरण selectedFruits.select(fruit=>fruit.id); को जोड़-तोड़ के साथ लागू किया जाएगा

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

0

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


0

धाराप्रवाह पर एक नज़र डालें , यह लगभग सब कुछ करता है जो LINQ करता है और पुनरावृत्तियों पर आधारित है - इसलिए यह नक्शे, जनरेटर के कार्यों, सरणियों, सब कुछ के साथ काम करता है।


0

सबसे समान सी # Selectएनालॉग एक mapफ़ंक्शन होगा। महज प्रयोग करें:

var ids = selectedFruits.map(fruit => fruit.id);

selectedFruitsसरणी से सभी आईडी का चयन करने के लिए ।

इसे किसी भी बाहरी निर्भरता की आवश्यकता नहीं है, बस शुद्ध जावास्क्रिप्ट। आप mapयहाँ दस्तावेज़ पा सकते हैं : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map


-1

मैं मूल प्रश्न के बजाय प्रश्न के शीर्षक का उत्तर दे रहा हूं जो अधिक विशिष्ट था।

जावास्क्रिप्ट और जनरेटर कार्यों और वस्तुओं की तरह जावास्क्रिप्ट की नई सुविधाओं के साथ, जावास्क्रिप्ट के लिए LINQ जैसा कुछ संभव हो जाता है। ध्यान दें कि linq.js, उदाहरण के लिए, नियमित रूप से अभिव्यक्ति का उपयोग करते हुए एक पूरी तरह से अलग दृष्टिकोण का उपयोग करता है, शायद उस समय भाषा में समर्थन की कमी को दूर करने के लिए।

कहा जा रहा है कि, मैंने जावास्क्रिप्ट के लिए एक LINQ लाइब्रेरी लिखी है और आप इसे https://github.com/Siderite/LInQer पर पा सकते हैं । Https://siderite.dev/blog/linq-in-javascript-linqer पर टिप्पणियाँ और चर्चा ।

पिछले उत्तरों से, केवल मणिपुला लगता है कि कोई जावास्क्रिप्ट में LINQ पोर्ट से क्या उम्मीद करेगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.