2011-01-26 21 views
15

के निकटतम किसी सरणी में संख्या प्राप्त करें, मेरे पास जावास्क्रिप्ट में पूर्णांक का एक ऐरे है, [5,10,15,20,25,30,35] जब कोई संख्या x दिया गया है, तो मैं उस संख्या के सबसे नज़दीकी सरणी में तत्व कैसे ढूंढ सकता हूं?किसी दिए गए नंबर

यदि संख्या एक मूल्य से अधिक है, लेकिन अगले नंबर तक आधा रास्ते से कम है, तो मैं छोटे मूल्य का चयन करूंगा, अगर यह अगले नंबर पर आधे रास्ते से अधिक हो, तो मैं उच्च संख्या का चयन करूंगा।

उदाहरण के लिए 7 वापस आ जाएगा, लेकिन 8 वापस आ जाएगा 10. मैं इसे कैसे पूरा कर सकता हूं? किसी भी मदद या सुझाव की सराहना की जाएगी। मैंने खोज की है और समाधान नहीं मिला है। मुझे यकीन है कि यह सामान्य है।

+5

सामान्य रूप से: आपने अभी तक क्या प्रयास किया है? –

+0

संभावित डुप्लिकेट [सरणी से निकटतम संख्या प्राप्त करें] (http://stackoverflow.com/questions/8584902/get-closest-number-out-of-array) –

+0

** अपने बिंदु से पूर्ण दूरी प्राप्त करें (जैसा कि वाई), तो उलटने कि वाई पैमाने पर करने के लिए (यह चारों ओर एक्स === 0.5, जहां वाई अधिकतम है) मापता है '(0.5 - Math.abs (0.5 - मूल्य))/0.5;' ** – neaumusic

उत्तर

11

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

सूची हमेशा पृथक नहीं किया जा रहा है, तो सबसे बड़ी संख्या < = लक्ष्य संख्या और छोटी का ट्रैक सूची रखने के माध्यम से जाना संख्या> = लक्ष्य संख्या। उस लक्ष्य को वापस करें जो लक्ष्य के सबसे नज़दीक है।

किसी भी समाधान में, आपको यह तय करने की आवश्यकता होगी कि किस पक्ष का पक्ष है यदि उदाहरण के लिए आप [1, 3] में 2 खोज रहे हैं।

0

सरणी मानते हुए सरणी में पूर्णांक की प्रत्येक आसन्न जोड़ी के माध्यम से कदम उठाया जाता है। प्रत्येक जोड़ी के लिए ("5 और 10" या "20 और 25" कहें), परीक्षण करें कि x उनके बीच है, और यदि ऐसा है, तो जो भी x (निचले हिस्से की ओर पूर्वाग्रह के साथ) के करीब है, ।

आपको x पहले नंबर (पहले नंबर लौटाएं) या अंतिम संख्या से अधिक (आखिरी संख्या लौटाएं) के लिए एक विशेष मामला भी चाहिए।

यदि सरणी सॉर्ट नहीं है, तो इसे पहले क्रमबद्ध करें।

+2

खैर अगर सरणी सॉर्ट हो जाता है , आप दो निकटतम संख्याओं को खोजने के लिए बस एक बाइनरी-सर्च (या बहुत अधिक कोई अन्य खोज) कर सकते हैं ... –

+0

@belisarius आप किस बिंदु को बनाने की कोशिश कर रहे हैं? – marcog

+0

@marcog मैं पिछली टिप्पणी का जवाब दे रहा था, लेकिन चला गया .. इसे हटा देगा –

5

अपनी मूल सरणी के समान आकार की एक अस्थायी सरणी बनाएं, और इसे अपने एक्स और सरणी तत्व के बीच अंतर के साथ पॉप्युलेट करें।

उदाहरण के लिए, अस्थायी सरणी अस्थायी [], हो सकता है और अपने मूल सरणी हो एक []:

temp[i]=Math.abs(x-a[i]); 

फिर, सूचकांक न्यूनतम मूल्य की अस्थायी [] में उपयोगकर्ता पर लौटने ।

16
function getClosest(array, target) { 
    var tuples = _.map(array, function(val) { 
     return [val, Math.abs(val - target)]; 
    }); 
    return _.reduce(tuples, function(memo, val) { 
     return (memo[1] < val[1]) ? memo : val; 
    }, [-1, 999])[0]; 
} 

तो एक कार्यात्मक दृष्टिकोण का उपयोग कर लागू होता है तो आप (मूल्य, दूरी) की tuples को सेट मैप कर सकते हैं तो छोटी से छोटी दूरी के साथ टपल के लिए tuples के उस समूह के कम। हम उस tuple में मूल्य वापस।

_.map के उपयोग की व्याख्या करने के लिए। आप अपने सरणी में सभी मानों को नए मानों पर मैप करते हैं और फ़ंक्शन नए मानों की सरणी वापस कर देगा। इस मामले में tuples की एक सरणी।

_.reduce के उपयोग की व्याख्या करने के लिए। आप सरणी को एक ही मान में कम करते हैं। आप एक सरणी और एक ज्ञापन में गुजरते हैं। जब आप सरणी के माध्यम से जाते हैं तो ज्ञापन आपका "चल रहा काउंटर" होता है।इस मामले में हम जांचते हैं कि वर्तमान ट्यूपल ज्ञापन के करीब है और यदि ऐसा है तो इसे ज्ञापन बनाएं। फिर हम अंत में ज्ञापन वापस कर देते हैं।

कोड स्निपेट के ऊपर underscore.js पर निर्भर करता है कार्यात्मक शैली जावास्क्रिप्ट

+0

बहुत बढ़िया जवाब .. धन्यवाद .. काटा और चिपकाया, एक इलाज करता है! –

+0

एक साइड-नोट के रूप में, लोडाश में गिरावट ~ 200 वस्तुओं की एक सूची दी गई, लोडाश अंडरस्कोर (~ 2 9 के ओप/सेकंड) संस्करण की तुलना में ~ 1.5x बेहतर (~ 45 के ओप/सेकंड) करता है। –

+0

बीटीडब्ल्यू, _.reduce को "tuples" सरणी पर एक संख्यात्मक क्रम के लिए बदल दिया जा सकता है; हालांकि, यह लगभग भी प्रदर्शन नहीं करता है। इसी तरह, tuples के बजाय किसी ऑब्जेक्ट/हैश का उपयोग करना अधिक पठनीय है, लेकिन यह भी खराब प्रदर्शन करता है। –

0

मैं अपने खुद के समारोह के बाद से मैं किसी भी है कि मेरे requeriments को पूरा करती है नहीं पा सके बनाई जुओं से भरा हुआ किरकिरा दूर करने के लिए।

function closest_number(quantities, number, closest_factor) 
    { 
     if (closest_factor == 'ceil') 
     { 
      quantities.sort(function(a, b) 
       { 
        return a - b 
       } 
      ); 

      for (var i = 0; i < quantities.length; i++) 
      { 
       if (quantities[i] >= number) 
       { 
        return quantities[i]; 
       } 

       last_value = quantities[i]; 
      } 

      return last_value; 
     } 
     else if (closest_factor == 'floor') 
     { 
      quantities.sort(function(a, b) 
       { 
        return a - b 
       } 
      ); 

      min_value = quantities[0]; 

      for (var i = 0; i < quantities.length; i++) 
      { 
       if (number == quantities[i]) 
       { 
        return number; 
       } 
       else if (quantities[i] < number) 
       { 
        min_value = quantities[i]; 
       } 
       else if(quantities[i] > number) 
       { 
        return min_value; 
       }   
      } 

      return min_value; 
     } 
     else 
     { 
      return false; 
     } 
    }; 
16

शायद सबसे आसान बात यह है कि संदर्भ मान x से दूरी पर आधारित है, और फिर पहला आइटम लें।

अंतर्निहित Array.prototype.sort() एक तुलनात्मक कार्य ले सकता है जिसे सरणी से मूल्यों के जोड़े के लिए बुलाया जाएगा। फिर कुंजी एक तुलनात्मक कार्य में बसने के लिए है जो संदर्भ मान x से उनकी दूरी के आधार पर दो मानों की तुलना करता है।

let x = 8; 
let array = [5, 10, 15, 20, 25, 30, 35]; 
let closest = array.sort((a, b) => Math.abs(x - a) - Math.abs(x - b))[0]; 

यह सरल demo देखें।

+1

थंब अप। बहुत सुरुचिपूर्ण समाधान। –

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