2010-05-09 9 views
13

jQuery में, filter() आपके परिणाम को उन तत्वों को कम कर देता है जो एक निश्चित स्थिति को पूरा करते हैं।jQuery: फ़िल्टर() का उपयोग करें, लेकिन दोनों परिणामों के साथ काम करें

यह सूची को दो भागों में विभाजित करता है। तत्वों की "अच्छा आधा" के साथ कार्य करना आसान है:

$("some selector").filter(function() { 
    // determine result... 
    return result; 
}).each(/* do something */); 

लेकिन यह कैसे मैं भी मेरी तत्वों की "अन्य आधा" के साथ काम कर सकते हैं - लेकिन के बराबर इस कर के बिना:

$("some selector").filter(function() { 
    // determine result... 
    return !result; 
}).each(/* do something else */); 

असल में, मैं एक अलग फ़िल्टर में दो अलग /* do something */ भागों को खिलाना चाहता हूं। उन लोगों के लिए जो मिलान करते हैं, और दूसरों के लिए एक - दो बार फ़िल्टर किए बिना। क्या मुझे एक jQuery फ़ंक्शन याद आ रहा है जो यह करता है?


पी.एस .: मुझे लगता है मैं कर सकता है:

$("some selector").each(function() { 
    // determine result... 
    if (result) 
    /* do something */ 
    else 
    /* do something else */ 
}); 

लेकिन मैं अच्छे के लिए कुछ के लिए उम्मीद की गई थी।

+0

मुझे लगता है कि यह 'प्रत्येक() 'होगा। – Matt

+2

http://jsfiddle.net/nZtRF/ शायद एक बात ध्यान देने योग्य है कि 'नहीं()' विधि के साथ, प्रदर्शन तेजी से घटता है क्योंकि तत्वों की संख्या बढ़ जाती है। छोटी मात्रा के लिए, यह मामूली है। बड़ी मात्रा में, आपको फ़िल्टर में 'if()' कथन का उपयोग करके बेहतर प्रदर्शन मिलेगा। उपरोक्त jsfiddle लिंक पर परीक्षण देखें, और मात्रा के साथ गड़बड़ करें। – user113716

+0

@patrick: बहुत सच है। यह एक गंभीर कमी है। : - \ – Tomalak

उत्तर

16

विधि प्लगइन रूप में कोबी द्वारा सिफारिश की:

$.fn.invert = function() { 
    return this.end().not(this); 
}; 

$('.foo').filter(':visible').hide().invert().show(); 

ध्यान दें कि invert() jQuery ढेर करने के लिए एक नए तत्व जोड़ नहीं होगा, लेकिन की जगह पिछले एक:

$('.foo').filter(':visible').invert().end(); // this will yield $('.foo'), not $('.foo:visible') 

संपादित करें: Tomalak के सुझाव पर prevObjectend() बदल दिया।

+0

स्वीट। :-) मुझे वास्तव में वह वाला अच्छा लगा। – Tomalak

+0

मेरा कोड जंजीर नहीं किया जा सकता है, और ऐसा लगता है कि यह बहुत अच्छी तरह से आसपास है। +1 – Kobi

+0

'prevObject' से बेहतर नहीं होगा()'? 'prevObject' का अर्थ है कि मुझे तुरंत पिछले चरण में फ़िल्टर करना होगा, जबकि 'अंत()' दस्तावेज़ों के अनुसार" सबसे हालिया फ़िल्टरिंग ऑपरेशन "को संदर्भित करता है, जिसका अर्थ है कि यह कई कदम पीछे हो सकता है। – Tomalak

0

दिलचस्प सवाल।

$("some selector").each(function() { 
    if ($(this).is(SOMEFILTER)) { 
    // do something 
    } else { 
    // do something 
    } 
    // continue with things that apply to everything 
}); 
+0

मैं एक और jQuery-शैली, विधि श्रृंखला समाधान के लिए उम्मीद कर रहा था; लेकिन 'प्रत्येक() 'तकनीकी रूप से काम करेगा। पीएस: यदि फ़िल्टर परिणाम किसी jQuery चयनकर्ता द्वारा निर्धारित नहीं किया जा सकता है, तो आप दुर्भाग्यवश 'is()' का उपयोग नहीं कर सकते हैं। – Tomalak

1

आप एक jQuery प्लगइन लेखन यह करने के लिए पर अपना हाथ की कोशिश कर सकते हैं: मैं आप मैं क्या सुझाव देने के लिए जा रहा था की ओर झुकाव रहे हैं। फ़िल्टर फ़ंक्शन का कोड देखें, और जो कुछ भी आप चाहते हैं उससे अधिक कुछ के साथ आएं।

$("some selector").processList(predicate, successCallback, failureCallback); 

फिर आप तीन कॉलबैक में पारित होगा:: यह की तरह कुछ हो सकता है एक है कि एक वस्तु का मूल्यांकन करता है अगर यह फिल्टर चयन का मिलान देखने के लिए (आप भी एक चयनकर्ता स्ट्रिंग, या की तरह स्वीकार करते हैं सकता है); वह जो ऑब्जेक्ट को चयन करता है जो चयन से मेल खाता है, और दूसरा जो ऑब्जेक्ट्स को संभालता है जो मेल नहीं खाता है।

+0

हाँ, ऐसा कुछ है जो मेरे मन में है। :) बहुत जटिल नहीं होगा, लेकिन मैं पहिया का पुन: आविष्कार नहीं करना चाहता था। – Tomalak

+0

हाँ, क्षमा करें। मुझे यकीन नहीं है कि ऐसी कोई चीज़ मौजूद है, पहले से ही। यदि आपको प्लगइन लिखने के तरीके की सहायता करने की आवश्यकता है, तो हमें बताएं =) – RMorrisey

+0

धन्यवाद। ^^ मुझे लगता है कि प्लगइन जो ऐसा करने में सक्षम होगा वह एक ब्रेनर है। मैं बस यह सुनिश्चित करने की कोशिश कर रहा हूं कि मुझे कुछ चालाक नहीं है जो पहले से ही jQuery में बनाया गया है। – Tomalak

1

अगर यह किसी भी अच्छे है मैं नहीं जानता, लेकिन filter() का उपयोग कर आप की तरह कुछ कर सकता है:

var $others = $(); 

var $filtered = $('div').filter(function() { 
    if(! your filter test) { 
     $others.push(this); 
    } else { 
     return true; 
    } 
}); 

alert($others.length); 
alert($filtered.length); 

संपादित करें:

सबसे पहले मैं एक खाली jQuery सेट के साथ शुरू इसे करने की कोशिश $(), और फिर गैर-फ़िल्टर परिणामों के साथ इसे पॉप्युलेट करने के लिए add() का उपयोग करके, लेकिन यह काम नहीं कर सका।

संपादित करें:

रूप Tomalak द्वारा सुझाए गए एक खाली jQuery वस्तु पर सीधे धक्का उपयोग करने के लिए अपडेट किया गया।

+0

एचएम, यह करने का एक तरीका होगा। बिल्कुल चिकनी नहीं, लेकिन व्यावहारिक। :) +1 (पीएस: jQuery एक सरणी है, आप सीधे 'पुश() 'का उपयोग कर सकते हैं) – Tomalak

+0

धन्यवाद, हाँ, अगर मैं' अन्य 'jQuery सेट को पॉप्युलेट करने का बेहतर तरीका जानता हूं तो यह थोड़ा अच्छा होगा फ़िल्टर – user113716

+0

@ टोमालक - बस jQuery ऑब्जेक्ट पर 'पुश()' का उपयोग करने के बारे में आपकी टिप्पणी देखी गई। समझ में आता है, इसलिए मैंने अपना जवाब अपडेट किया। धन्यवाद। – user113716

10

मैं आमतौर पर इस बात के लिए not का उपयोग करें - यह तत्वों की एक सरणी लेते हैं और उन्हें अपने चयन से हटा सकते हैं, पूरक के साथ छोड़:

var all = $("some selector"); 
var filtered = all.filter(function() { 
    // determine result... 
    return result; 
}); 
var others = all.not(filtered); 
+0

अच्छा एक। मुझे पता नहीं था कि 'नहीं()' इस तरह से काम करता है। +1 – Tomalak

+0

+1 - मेरा से बेहतर। पारितोषिक के लिए धन्यवाद। – user113716

+0

वास्तव में बहुत ही सुरुचिपूर्ण। – Bora

1
$.fn.if = function(cond, ontrue, onfalse) { 
    this.each(function() { 
    if (cond.apply(this)) ontrue.apply(this); 
    else onfalse.apply(this); 
    }); 
}; 

$('some selector').if(function() { 
    // determine result 
}, function() { 
    // do something 
}, function() { 
    // do something else 
}); 

मैं सुनिश्चित नहीं हूं कि यह बहुत अधिक है हालांकि, मैन्युअल रूप से प्रत्येक के अंदर एक डालने से पठनीय।

+0

आपको इंडेक्स को 'cond.apply()' के लिए तर्क के रूप में जोड़ना होगा क्योंकि jQuery स्वयं फ़ंक्शन फ़िल्टर करने के लिए वर्तमान इंडेक्स को फ़ीड करता है। और आपको जाहिर है, 'cond, ontrue, onfalse' तर्कों के लिए टाइप चेक जोड़ना होगा। इसके अलावा, यह मेरे मन में था। एक बार जब आप jQuery में 5 विधियों की श्रृंखला बनाते हैं, तो पठनीयता वैसे भी पीड़ित होती है। ;) – Tomalak

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