2012-11-26 33 views
15

की मैं इस तरह की वस्तुओं की एक बड़ी (1000+) सूची है मान लेते हैं:जावास्क्रिप्ट में JSON ऑब्जेक्ट्स की सूची फ़िल्टर करने का उच्चतम प्रदर्शन तरीका क्या है?

[{name: 'john dow', age: 38, gender:'m'}, {name: 'jane dow', age: 18, gender:'f'}, ..] 

मैं नाम (चरित्र वार) द्वारा इस सूची को फ़िल्टर करना चाहते हैं।

filter('j') => [{name: 'john dow', age: 38, gender:'m'}, {name: 'jane dow', age: 18, gender:'f'}, ..] 

filter('jo') => [{name: 'john dow', age: 38, gender:'m'}, ..] 

filter('dow') => [{name: 'john dow', age: 38, gender:'m'}, {name: 'jane dow', age: 18, gender:'f'}, ..] 

ऐसा करने का उच्चतम प्रदर्शन तरीका क्या है? RegEx स्पष्ट रूप से चाबियों में से एक है, सूची को ऑर्डर करने से पहले अगर आप मानते हैं कि उपयोगकर्ता आमतौर पर शुरुआत से नाम शुरू करना चाहता है तो यह भी एक अच्छा विचार हो सकता है, लेकिन यह केवल कुछ मामलों में मदद करता है।

क्या फ़िल्टर करने के लिए कोई जावास्क्रिप्ट अंतर्निहित कार्य है? मैं उम्मीद करता हूं कि वे जावास्क्रिप्ट कार्यान्वयन से तेज़ हों।

पीएस .: हाँ, मैं ऑफ़लाइन क्षमताओं के कारण क्लाइंट पक्ष पर फ़िल्टर करना चाहता हूं।

+3

असल में यदि वे जावास्क्रिप्ट में ऑब्जेक्ट्स हैं, तो वे अब JSON नहीं हैं। "JSON" * केवल * नेटवर्क पर उस जानकारी को स्थानांतरित करने के लिए उपयोग किया जाने वाला नोटेशन (या संभवतः इसे संग्रहीत करता है)। एक जावास्क्रिप्ट प्रोग्राम के अंदर वे केवल "जावास्क्रिप्ट ऑब्जेक्ट्स" होते हैं (जब तक कि आप एक स्ट्रिंग के बारे में बात नहीं कर रहे हैं जिसमें * एन्कोडेड JSON डेटा शामिल है, इस मामले में आपको इसे और अधिक काम करने से पहले जावास्क्रिप्ट ऑब्जेक्ट्स में कनवर्ट करना चाहिए)। –

+0

यदि आप "ओह" खोजते हैं तो क्या होगा? –

+0

@ जोचिमसॉयर आप सही हैं ..मैंने इसे ठीक किया;) फ़िल्टर ('ओहएन') => [{नाम: 'जॉन डॉव', आयु: 38, लिंग: 'एम'}, ..] – wzr1337

उत्तर

10

हालांकि एक substring index (जैसे एक Suffix tree के रूप में) यह तेजी से होगा, प्रत्यक्ष खोज होगा:

function (s, l) { 
    return l.filter(function (v) { 
     return v.name.find(s) !== -1; 
    }); 
} 

जहां s क्वेरी स्ट्रिंग है और l वस्तुओं की सूची है।

+2

एक सीधी 'फॉर' लूप देशी फ़िल्टर की तुलना में कम से कम दोगुना होगा। https://jsperf.com/array-filter-performance – Mrchief

+0

@ डैन डी। आप एक सबस्ट्रिंग इंडेक्स का जिक्र करते हैं। क्या एक उदाहरण देना संभव है? मेरे पास ऑफलाइन खोज कार्यक्षमता के साथ एक समान अनुप्रयोग है। वर्तमान में खोज करने के लिए 200,000 ऑब्जेक्ट्स नियमित रूप से पर्याप्त नहीं है। इस पैटर्न को लागू करने के लिए नियमित रूप से 'फिल्टर() ' – mesqueeb

9

अनुभव से, निम्नलिखित कलन विधि काफी अच्छी तरह से काम करता है:

  1. उपयोगकर्ता प्रकार पहले अक्षर, आप (एक खोज Array.filter() शायद और दुकान का उपयोग कर कि जो कुछ भी उपयोगकर्ता प्रकार के तहत परिणाम प्रदर्शन जब उदाहरण के लिए "जे");

  2. उपयोगकर्ता प्रकार एक अन्य पत्र (उदाहरण के लिए "ओ"), आप पर खोज जो कुछ भी करने से पहले ("j") टाइप किया गया था करते हैं, वस्तुओं की संख्या को कम करने

  3. जब उपयोगकर्ता हटाए गए के माध्यम से जाना खोज बॉक्स में जो कुछ भी बचा है, उसके आधार पर संग्रहीत खोजों को ढूंढने का प्रयास करने वाले एक या अधिक वर्ण; यदि सभी विफल हो जाते हैं, तो आप एक खाली सूची दिखाते हैं और पहले संग्रहीत खोजों को अमान्य कर देते हैं।

+0

किसी भी पुस्तकालय/कोड नमूने के साथ पर्याप्त तेज़ नहीं है? –

+0

मुझे लगता है कि यह एक बहुत अच्छा दृष्टिकोण है ... क्या आप किसी लाइब्रेरी को उपयोग करने के लिए तैयार हैं? –

4

मैं इस मामले में प्रदर्शन के बारे में बहुत ज्यादा चिंता नहीं करता। डेस्कटॉप कंप्यूटर को पसीने के बिना 1000, या 10,000 मूल्यांकन खाना चाहिए। मैं किसी भी तरह के जटिल अनुकूलन से बचूंगा क्योंकि कार्यक्षमता तोड़ने का जोखिम शायद थोड़ा कुशल प्रसंस्करण के लाभ से अधिक है।

जावास्क्रिप्ट (ईसीएमएस्क्रिप्ट 5) एरे फ़िल्टर करने के लिए नई विधियां प्रदान करता है। एक मूल विधि के रूप में यह थोड़ा तेज होना चाहिए।

var regex = ... 

results = json.filter(function(result) { 
    return regex.test(result.name) 
} 

Array.prototype.filter आधुनिक ब्राउज़रों में समर्थित है, http://kangax.github.com/es5-compat-table/ देखते हैं। पुराने ब्राउज़र के लिए एक पैच इस के साथ जोड़ा जा सकता है: https://github.com/kriskowal/es5-shim