जावास्क्रिप्ट में एक ऐरे का न्यूनतम / अधिकतम तत्व खोजें


778

मैं जावास्क्रिप्ट ऐरे का न्यूनतम या अधिकतम तत्व आसानी से कैसे प्राप्त कर सकता हूं?

उदाहरण Psuedocode:

let array = [100, 0, 50]

array.min() //=> 0
array.max() //=> 100

93
नोट: ECMAScript 6 के साथ आप नए उपयोग कर सकते हैं प्रसार ऑपरेटर : (तीन डॉट्स ...के साथ) Math.max()इस तरह: Math.max(...[2, 5, 16, 1])MDN प्रलेखन से बने मेरे उत्तर को देखें ।
टोटमेडली

1
एक उत्तर के रूप में चिह्नित करने पर विचार करें।
एलेक्स

यहां सबसे आम तरीकों की तुलना करने के लिए एक बेंचमार्क है: jsben.ch/#/1QuTg
EscapeNetscape

es6 मूल रूप से शानदार है! :)
डेटिनडोकॉक

बिना ES6 Math.max.apply(null, [2,5,16,1])
तोमर

जवाबों:


827

कैसे उपयोग करने के लिए Math.max/ Math.minइसके बजाय निर्मित सरणी वस्तु को बढ़ाने के बारे में :

Array.prototype.max = function() {
  return Math.max.apply(null, this);
};

Array.prototype.min = function() {
  return Math.min.apply(null, this);
};

यहाँ एक JSFiddle है

बिल्ट-इन को संवर्धित करना अन्य पुस्तकालयों (कुछ देखें) के साथ टकराव का कारण बन सकता है, इसलिए आप सीधे अपने सरणी में केवल apply'आईएनजी' के साथ अधिक आरामदायक हो सकते Math.xxx()हैं:

var min = Math.min.apply(null, arr),
    max = Math.max.apply(null, arr);

वैकल्पिक रूप से, अपने ब्राउज़र को संभालने से ECMAScript 6 का समर्थन होता है, आप प्रसार ऑपरेटर का उपयोग कर सकते हैं जो applyविधि के समान कार्य करता है:

var min = Math.min( ...arr ),
    max = Math.max( ...arr );

8
@ हंक: पास nullया Mathया {}जो भी apply()या call()जिसके परिणाम पर कोई असर नहीं है। आंतरिक रूप से Math.maxसंदर्भ नहीं देना चाहिए और न ही this
Roatin Marth

31
C # प्रोग्रामर के रूप में मुझे दृढ़ता से टाइप किए गए प्रश्नों की आवश्यकता है।
चाओसपांडियन

7
बस एक jQuery की गलती को साझा करते हुए मैं ऊपर दिए गए कोड के साथ बना रहा था, जो मुझे डीबग करने में लंबा समय लगा। एक jquery सरणी सब कुछ ठीक है, लेकिन iPad पर काम करता है। मुझे इसे काम करने के लिए सरणी को एक सच्चे देशी सरणी में बदलना था। केवल किसी कारण के लिए एकल उपकरण को प्रभावित कियाMath.max.apply(null, $.makeArray(array));
Forrest

11
मैंने डाउनवोट किया है, क्योंकि प्रस्तावित दृष्टिकोण स्टैक फ्रेम में ओ (एन) मेमोरी की खपत करता है, और परिणामस्वरूप बड़े सरणियों पर क्रैश होता है। मेरे मामले में सिर्फ नोड्स को क्रैश करने के लिए लगभग 130000 नंबर पर्याप्त थे।
एलेक्सी टिमानोव्स्की

14
इस तरह से निर्मित प्रोटोटाइप में वृद्धि न करें। यह अन्य पुस्तकालयों के साथ संघर्ष के बारे में नहीं है; यह उस क्षमता के बारे में भी है जो ब्राउज़र भविष्य में स्वयं .maxया एक .minविधि प्रदान करता है । पूरी तरह से यथार्थवादी परिदृश्य: आप इस उत्तर का उपयोग करते हैं। 2016 में, ES7 या ES8 कल्पना Array.maxऔर Array.min। इस संस्करण के विपरीत, वे स्ट्रिंग्स पर काम करते हैं। आपका भविष्य का सहकर्मी अब-अच्छी तरह से प्रलेखित मूल .max()पद्धति के साथ एक सरणी में वर्णानुक्रम-नवीनतम स्ट्रिंग प्राप्त करने की कोशिश करता है , लेकिन रहस्यमय तरीके से प्राप्त होता है NaN। घंटों बाद, वह इस कोड को ढूंढती है, एक चलती है git blame, और आपके नाम को शाप देती है।
मार्क अमेरी

362
var max_of_array = Math.max.apply(Math, array);

पूर्ण चर्चा के लिए देखें: http://aaroncrane.co.uk/2008/11/javascript_max_api/


13
बीच क्या अंतर है Math.max.apply(Math, array)और Math.max.apply(null, array)? ब्लॉग कहता है "... आपको फिर से यह कहना होगा कि वह फिर maxसे है Math...", लेकिन ऐसा लगता है कि मुझे ऐसा करने की आवश्यकता नहीं है ( applyजैसा कि पहले तर्क सेट करके null)।
ज़ियायुंग

9
@ziyuang जब आप ऐसा कहते हैं Math.max(a,b), Mathके रूप में पारित हो जाता है thisमूल्य है, इसलिए इसे जब साथ बुला भी ऐसा ही करने का कोई मतलब हो सकता है apply। लेकिन मूल्य का Math.maxउपयोग नहीं करता है this, इसलिए आप जो भी मूल्य चाहते हैं उसे पास कर सकते हैं।
ओरिओल

199

बड़े सरणियों (~ 10⁷ तत्वों) के लिए, Math.minऔर Math.maxदोनों Node.js. में निम्न त्रुटि उत्पन्न करते हैं

रेंजError: अधिकतम कॉल स्टैक का आकार पार हो गया

एक अधिक मजबूत समाधान कॉल स्टैक में प्रत्येक तत्व को जोड़ना नहीं है, बल्कि इसके बजाय एक सरणी पास करना है:

function arrayMin(arr) {
  return arr.reduce(function (p, v) {
    return ( p < v ? p : v );
  });
}

function arrayMax(arr) {
  return arr.reduce(function (p, v) {
    return ( p > v ? p : v );
  });
}

यदि आप गति के बारे में चिंतित हैं, तो निम्न कोड ~ 3 गुना तेज है, फिर Math.max.applyमेरे कंप्यूटर पर है। Http://jsperf.com/min-and-max-in-array/2 देखें ।

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (arr[len] < min) {
      min = arr[len];
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (arr[len] > max) {
      max = arr[len];
    }
  }
  return max;
};

यदि आपकी सरणियों में संख्याओं के बजाय तार होते हैं, तो आपको उन्हें संख्याओं में समेटने की भी आवश्यकता होती है। नीचे दिया गया कोड ऐसा करता है, लेकिन यह मेरी मशीन पर कोड को ~ 10 गुना धीमा कर देता है। Http://jsperf.com/min-and-max-in-array/3 देखें ।

function arrayMin(arr) {
  var len = arr.length, min = Infinity;
  while (len--) {
    if (Number(arr[len]) < min) {
      min = Number(arr[len]);
    }
  }
  return min;
};

function arrayMax(arr) {
  var len = arr.length, max = -Infinity;
  while (len--) {
    if (Number(arr[len]) > max) {
      max = Number(arr[len]);
    }
  }
  return max;
};

असाइन करें minऔर maxअंतिम तत्व और 1 ( while(--len));) द्वारा पुनरावृत्तियों को कम करने के लिए
वेणुगोपाल

@ वेणुगोपाल तब आपको यह देखने के लिए एक विशेष जांच की आवश्यकता है कि क्या सरणी खाली है और +/- इन्फिनिटी
लाइनस अननेबेक

2
अजीब ... मैं लिंक की गई वेबसाइट पर गया ... और फ़ायरफ़ॉक्स में परीक्षण 51.0.0 / मैक ओएस एक्स 10.12.0, कम-आधारित दृष्टिकोण लूप-आधारित की तुलना में 30% धीमा है ... बहुत अलग परिणाम
पियरपोलो सीरा

2
very different results आपने इसे 5 साल बाद किया)
Алексей Лекук

1
2019 में reduceसमाधान सबसे धीमा है। यहां तक ​​कि अगर आप एक सरणी के साथ काम करते हैं जिसमें लाखों तत्व हैं, तो लूप के लिए मानक का उपयोग करना बेहतर हैअधिक के लिए मेरा जवाब देखें।
तात्यामेली

152

स्प्रेड ऑपरेटर (ES6) का उपयोग करना

Math.max(...array);  // the same with "min" => Math.min(...array);


8
यह समाधान पहले से ही कई अन्य उत्तरों द्वारा प्रदान किया गया था ।
तात्मीडली

15
मैथ.मैक्स (... []) = -इनफिनिटी। हाहा 18
डेविड पोर्टाबेला

@DavidPortabella को यकीन नहीं है कि यह मज़ेदार क्यों है। यह विनिर्देश के अनुसार कैसे काम करता है :If no arguments are given, the result is -∞.
पैट्रिक रॉबर्ट्स

3
हां, मेरा मतलब था कि जावास्क्रिप्ट विनिर्देश भयानक है। यह स्पष्ट प्रतीत होता है कि बिना संख्या के मिनट की गणना नहीं की जा सकती है। अन्य गंभीर प्रोग्रामिंग भाषाओं में, जैसे कि स्काला, एक खाली सरणी के मिनट के लिए पूछना एक अपवाद फेंकता है।
डेविड पोर्टेबेला

3
स्काला उन लोगों के लिए है जिन्हें यह बताने के लिए मशीन की जरूरत है कि उन्होंने यह गलत किया है
थेडानोटो 4

106

tl; डॉ

// For regular arrays:
var max = Math.max(...arrayOfNumbers);

// For arrays with tens of thousands of items:
let max = testArray[0];
for (let i = 1; i < testArrayLength; ++i) {
  if (testArray[i] > max) {
    max = testArray[i];
  }
}

MDN समाधान

पर सरकारी MDN डॉक्सMath.max() पहले से ही इस मुद्दे को शामिल किया गया:

निम्नलिखित फ़ंक्शन एक संख्यात्मक सरणी में अधिकतम तत्व को खोजने के लिए Function.prototyp.apply () का उपयोग करता है । getMaxOfArray([1, 2, 3])के बराबर है Math.max(1, 2, 3), लेकिन आप getMaxOfArray()किसी भी आकार के प्रोग्रामेटिक रूप से निर्मित सरणियों पर उपयोग कर सकते हैं ।

function getMaxOfArray(numArray) {
    return Math.max.apply(null, numArray);
}

या नए प्रसार ऑपरेटर के साथ , एक सरणी की अधिकतम प्राप्त करना बहुत आसान हो जाता है।

var arr = [1, 2, 3];
var max = Math.max(...arr);

एक सरणी का अधिकतम आकार

MDN के अनुसारapply और प्रसार समाधान था कि तर्क की अधिकतम संख्या की सीमा से आया 65536 की एक सीमा:

लेकिन सावधान रहें: इस तरह से लागू करने में, आप जावास्क्रिप्ट इंजन की तर्क लंबाई सीमा से अधिक होने का जोखिम चलाते हैं। फ़ंक्शन को बहुत सारे तर्कों के साथ लागू करने के परिणाम (दसियों हज़ारों से अधिक तर्कों पर विचार करें) इंजनों में भिन्न होते हैं ( JavaScriptCore में हार्ड-कोडेड तर्क सीमा 65536 है ), क्योंकि सीमा (वास्तव में किसी भी अत्यधिक-बड़े-स्टैक की प्रकृति भी) व्यवहार) अनिर्दिष्ट है। कुछ इंजन एक अपवाद फेंक देंगे। अधिक खतरनाक रूप से, अन्य लोग मनमाने ढंग से उन तर्कों की संख्या को सीमित कर देंगे जो वास्तव में लागू फ़ंक्शन में पारित हो गए हैं। इस उत्तरार्द्ध मामले को स्पष्ट करने के लिए: यदि इस तरह के इंजन में चार तर्कों की सीमा होती है (वास्तविक सीमाएं निश्चित रूप से काफी अधिक होती हैं), तो ऐसा होगा जैसे कि तर्कों 5, 6, 2, 3 को उपरोक्त उदाहरणों में लागू करने के लिए पारित किया गया था, पूर्ण सरणी के बजाय।

वे एक हाइब्रिड समाधान भी प्रदान करते हैं जिसमें अन्य समाधानों की तुलना में वास्तव में अच्छा प्रदर्शन नहीं होता है। अधिक के लिए नीचे प्रदर्शन परीक्षण देखें।

2019 में वास्तविक सीमा कॉल स्टैक का अधिकतम आकार है । आधुनिक क्रोमियम आधारित डेस्कटॉप ब्राउज़रों के लिए इसका मतलब है कि जब यह न्यूनतम / अधिकतम के साथ न्यूनतम / अधिकतम खोजने के लिए आता है apply, तो व्यावहारिक रूप से केवल सरणियों के लिए अधिकतम आकार ~ 120000 है । इसके ऊपर, एक स्टैक ओवरफ्लो होगा और निम्नलिखित त्रुटि डाली जाएगी:

रेंजError: अधिकतम कॉल स्टैक का आकार पार हो गया

नीचे दी गई स्क्रिप्ट के साथ ( इस ब्लॉग पोस्ट पर आधारित ), उस त्रुटि को पकड़कर आप अपने विशिष्ट वातावरण के लिए सीमा की गणना कर सकते हैं।

चेतावनी! इस स्क्रिप्ट को चलाने में समय लगता है और आपके सिस्टम के प्रदर्शन के आधार पर यह आपके ब्राउज़र / सिस्टम को धीमा या क्रैश कर सकता है!

let testArray = Array.from({length: 10000}, () => Math.floor(Math.random() * 2000000));
for (i = 10000; i < 1000000; ++i) {
  testArray.push(Math.floor(Math.random() * 2000000));
  try {
    Math.max.apply(null, testArray);
  } catch (e) {
    console.log(i);
    break;
  }
}

बड़े सरणियों पर प्रदर्शन

एस्केपनेटस्केप की टिप्पणी में परीक्षण के आधार पर मैंने कुछ बेंचमार्क बनाए जो 100000 वस्तुओं के साथ यादृच्छिक संख्या केवल सरणी पर 5 विभिन्न तरीकों का परीक्षण करते हैं ।

2019 में, परिणाम बताते हैं कि मानक लूप (जिसमें बीटीडब्लू का आकार सीमा नहीं है) हर जगह सबसे तेज है। applyऔर प्रसार इसके बाद करीब आता है, फिर बाद में एमडीएन के हाइब्रिड समाधान के reduceरूप में सबसे धीमा।

लगभग सभी परीक्षणों ने एक ही परिणाम दिया, एक को छोड़कर जहां कुछ फैलता हुआ सबसे धीमा था।

यदि आपके पास 1 मिलियन आइटम रखने के लिए अपने सरणी को बढ़ाते हैं, तो चीजें टूटने लगती हैं और आप एक तेज समाधान के reduceरूप में और धीमी के रूप में मानक लूप के साथ छोड़ दिए जाते हैं ।

JSPerf बेंचमार्क

किसी सरणी के न्यूनतम / अधिकतम आइटम को खोजने के लिए jsperf.com बेंचमार्क विभिन्न समाधानों के लिए परिणाम है

JSBen बेंचमार्क

किसी सरणी के मिनट / अधिकतम आइटम को खोजने के लिए विभिन्न समाधानों के लिए jsben.com बेंचमार्क परिणाम

JSBench.me बेंचमार्क

किसी सरणी के न्यूनतम / अधिकतम आइटम को खोजने के लिए विभिन्न समाधानों के लिए jsbench.me बेंचमार्क परिणाम

बेंचमार्क स्रोत कोड


यदि आप टाइपस्क्रिप्ट का उपयोग कर रहे हैं, तो दिखाए गए प्रसार ऑपरेटर को Math.max.apply(Math, arr)'अधिकतम' संगतता के लिए संकलित किया जाता है ।
साइमन_वेक

1
एमडीएन से भी: "दोनों फैलते हैं (...)और applyया तो विफल होंगे या गलत परिणाम लौटाएंगे यदि सरणी में बहुत सारे तत्व हैं [...] कम समाधान में यह समस्या नहीं है" क्रोम, एफएफ, एज और IE11 का परीक्षण करना ऐसा लगता है कि यह है 100k मान तक की सरणी के लिए ठीक है। (Win10 और नवीनतम ब्राउज़रों पर परीक्षण किया गया: क्रोम 110k, फ़ायरफ़ॉक्स 300k, एज 400k, IE11 150k)।
ओरियाडैम

यह एक बहुत धीमी विधि है, क्या होगा यदि सरणी में हजारों तत्व होंगे?
स्लाव फोमिन II

@SlavaFominII मैंने उत्तर को विस्तारित किया ताकि यह हजारों तत्वों के साथ सरणियों को कवर करे।
तात्यामेली

68

यदि आप मेरे बारे में उपयोग करने के बारे में पागल हैं Math.max.apply(जो एमडीएन के अनुसार बड़े एरेज दिए जाने पर त्रुटियां पैदा कर सकते हैं ), तो यह कोशिश करें:

function arrayMax(array) {
  return array.reduce(function(a, b) {
    return Math.max(a, b);
  });
}

function arrayMin(array) {
  return array.reduce(function(a, b) {
    return Math.min(a, b);
  });
}

या, ES6 में:

function arrayMax(array) {
  return array.reduce((a, b) => Math.max(a, b));
}

function arrayMin(array) {
  return array.reduce((a, b) => Math.min(a, b));
}

अनाम फ़ंक्शंस दुर्भाग्य से आवश्यक हैं (उपयोग करने के बजाय Math.max.bind(Math)क्योंकि reduceयह केवल पास aऔर bइसके फ़ंक्शन के लिए नहीं है, लेकिन यह भी iऔर सरणी के लिए एक संदर्भ है, इसलिए हमें यह सुनिश्चित करना होगा कि हम maxउन पर भी कॉल करने की कोशिश न करें ।


आपका ईएस 6 उदाहरण, क्या कोई कारण है जो सिर्फ वापस नहीं आता है Math.max(...array)?
वोज्शिएक बेडनार्स्की

@WojciechBednarski इस पृष्ठ पर यह सुझाव दिया गया है कि प्रसार ऑपरेटर का उपयोग सरणी को applyपास करने के समान है, और इसलिए इसमें समान डाउनसाइड (अधिकतम तर्क सीमा) है।
डैनियल बकमास्टर

इसके लिए धन्यवाद। बस आप कम होने के बाद लापता ब्रैकेट को सही कर सकते हैं:function arrayMax(array) { return array.reduce(function(a, b) { return Math.max(a, b); }); // <--------- missing ) }
अरकोव्स्की

1
@DanielDietrich मुझे लगता है कि Math.min()कोई भी मान, रिटर्न के साथ कॉल करने के बराबर है Infinity, इसलिए ये फ़ंक्शन reduce(..., Infinity)उस व्यवहार से मेल खाने के लिए उपयोग कर सकते हैं । मैं इसे अपवाद के रूप में फेंकना पसंद करता हूं (जैसा कि वर्तमान में है), क्योंकि खाली सरणी के न्यूनतम लेने से त्रुटि होने की संभावना है।
डैनियल बकमास्टर

1
अब तक की कमी सबसे धीमी है।
Алексей Лещук

40

.apply अक्सर इसका उपयोग तब किया जाता है जब इरादा तर्क मानों की सूची के साथ एक वैरेडिक फ़ंक्शन को लागू करना होता है, जैसे

Math.max([value1[,value2, ...]])समारोह शून्य या अधिक संख्या में से सबसे बड़ी देता है।

Math.max(10, 20); // 20
Math.max(-10, -20); // -10
Math.max(-10, 20); // 20

Math.max()विधि आप एक सरणी में पारित करने के लिए अनुमति नहीं है। यदि आपके पास उन मूल्यों की एक सूची है, जिनके लिए आपको सबसे बड़ा प्राप्त करने की आवश्यकता है, तो आप सामान्य रूप से Function.prototyp.apply () का उपयोग करके इस फ़ंक्शन को कॉल करेंगे , उदाहरण के लिए

Math.max.apply(null, [10, 20]); // 20
Math.max.apply(null, [-10, -20]); // -10
Math.max.apply(null, [-10, 20]); // 20

हालाँकि, ECMAScript 6 के अनुसार आप प्रसार ऑपरेटर का उपयोग कर सकते हैं :

प्रसार ऑपरेटर उन स्थानों में अभिव्यक्ति का विस्तार करने की अनुमति देता है जहां कई तर्क (फ़ंक्शन कॉल के लिए) या कई तत्व (सरणी लीटर के लिए) अपेक्षित हैं।

प्रसार ऑपरेटर का उपयोग करके, उपरोक्त को इस तरह से फिर से लिखा जा सकता है:

Math.max(...[10, 20]); // 20
Math.max(...[-10, -20]); // -10
Math.max(...[-10, 20]); // 20

वेरिएडिक ऑपरेटर का उपयोग करके फ़ंक्शन को कॉल करते समय, आप अतिरिक्त मान भी जोड़ सकते हैं, जैसे

Math.max(...[10, 20], 50); // 50
Math.max(...[-10, -20], 50); // 50

बक्शीश:

प्रसार ऑपरेटर के संयोजन का उपयोग, आप शाब्दिक शृंखला सिंटैक्स का उपयोग करने स्थितियों में, जहां ES5 में आप जरूरी कोड में वापस आने की आवश्यकता होगी में नए सरणियों बनाने के लिए सक्षम बनाता है push, spliceआदि

let foo = ['b', 'c'];
let bar = ['a', ...foo, 'd', 'e']; // ['a', 'b', 'c', 'd', 'e']

1
बोनस में आपका अंतिम उदाहरण concatअधिकांश प्रोग्रामर्स द्वारा उपयोग करके लिखा जाएगा क्योंकि यह आपको एक पंक्ति शैली को बनाए रखने देता है।
कोडी एलन टेलर

31

दो तरीके छोटे और आसान हैं:

let arr = [2, 6, 1, 0]

रास्ता 1 :

let max = Math.max.apply(null, arr)

रास्ता 2 :

let max = arr.reduce(function(a, b) {
    return Math.max(a, b);
});

यह देखें कि क्या सरणी खाली है - आपको नकारात्मक अनंतता मिलेगी जो कि आप नहीं चाहते हैं। यदि आप प्राप्त करना चाहते हैं 0तो आप उपयोग कर सकते हैं [0].concat(arr)या फैलाने वाले सिंटैक्स के साथ [0, ...arr]('गिरफ्तारी' के स्थान पर)
Simon_Weaver

22

आप इसे सरणी प्रकार बढ़ाकर करते हैं:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};
Array.min = function( array ){
    return Math.min.apply( Math, array );
}; 

यहाँ से बढ़ाया (जॉन रेजिग द्वारा)


20

Arrayतत्वों का एक न्यूनतम मूल्य खोजने के लिए एक सरल समाधान Arrayप्रोटोटाइप फ़ंक्शन का उपयोग करना है reduce:

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min ? val : min, A[0]); // returns -9

या जावास्क्रिप्ट का उपयोग कर बनाया गया Math.in () फ़ंक्शन (धन्यवाद @Tenflex):

A.reduce((min,val) => Math.min(min,val), A[0]);

यह सेट करता minहै A[0], और फिर A[1]...A[n]यह जांचता है कि क्या यह कड़ाई से कम है min। यदि A[i] < minफिर minअद्यतन किया जाता है A[i]। जब सभी सरणी तत्वों को संसाधित किया गया है, minतो परिणाम के रूप में लौटाया जाता है।

संपादित करें : न्यूनतम मूल्य की स्थिति शामिल करें:

A = [4,3,-9,-2,2,1];
A.reduce((min, val) => val < min._min ? {_min: val, _idx: min._curr, _curr: min._curr + 1} : {_min: min._min, _idx: min._idx, _curr: min._curr + 1}, {_min: A[0], _idx: 0, _curr: 0}); // returns { _min: -9, _idx: 2, _curr: 6 }

3
A.reduce ((मिनट, वैल) => मैथ.मिन (मिनट, वैल), ए [0]); इससे भी कम
टेनफ्लेक्स

एक बोनस प्रश्न के रूप में, कैसे न केवल minमान लौटाया गया है, बल्कि एरे में भी इसकी स्थिति है?
स्टीववे

@meshfields - मैंने जवाब अपडेट कर दिया है।
निकोलस लाइके इवरसेन

15

दूसरों ने पहले से ही कुछ समाधान दिए हैं जिसमें वे वृद्धि करते हैं Array.prototype। मैं इस उत्तर में सभी स्पष्ट करना चाहता हूं कि यह होना चाहिए Math.min.apply( Math, array )या नहीं Math.min.apply( null, array )तो क्या संदर्भ का उपयोग किया जाना चाहिए, Mathया null?

जब nullसंदर्भ के रूप में पास किया जाता है apply, तो संदर्भ वैश्विक ऑब्जेक्ट ( windowब्राउज़र के मामले में ऑब्जेक्ट) पर डिफ़ॉल्ट होगा । पासिंग Mathसंदर्भ के रूप में वस्तु सही समाधान होगा, लेकिन इसे पारित चोट नहीं होगा nullया तो। यहां एक उदाहरण है जब समारोह को nullसजाते समय परेशानी हो सकती है Math.max:

// decorate Math.max
(function (oldMax) {
    Math.max = function () {
        this.foo(); // call Math.foo, or at least that's what we want

        return oldMax.apply(this, arguments);
    };
})(Math.max);

Math.foo = function () {
    print("foo");
};

Array.prototype.max = function() {
  return Math.max.apply(null, this); // <-- passing null as the context
};

var max = [1, 2, 3].max();

print(max);

उपरोक्त एक अपवाद को फेंक देगा क्योंकि this.fooमूल्यांकन किया जाएगा window.foo, जो कि है undefined। अगर हम बदलने के nullसाथ Math, बातें की उम्मीद है और स्ट्रिंग "foo" स्क्रीन पर प्रिंट किया जाएगा के रूप में काम करेंगे (मैं इस का उपयोग कर परीक्षण किया मोज़िला राइनो )।

आप बहुत हद तक यह मान सकते हैं कि किसी ने भी सजाया Math.maxनहीं है, पास nullकरना समस्याओं के बिना काम करेगा।


2
मुद्दा लेना। हालाँकि कोई क्यों सजायेगा Foo.staticMethodऔर संदर्भ देगा this? कि डेकोरेटर के डिजाइन में गलती नहीं होगी? (जब तक कि वे वैश्विक दायरे को संदर्भित नहीं करना चाहते थे , और जब तक राइनो का उपयोग किया जा रहा है, तब तक जावास्क्रिप्ट इंजन से स्वतंत्र रहना चाहते हैं )।
रोहिन मार्थ

1
यह कल्पना स्पष्ट है कि किन निर्दिष्ट कार्यों को " इस मान" का उल्लेख करना चाहिए (वास्तव में, यह वाक्यांश विनिर्देश में 125 बार दिखाई देता है)। Math.max, प्रति युक्ति लागू किया जाता है, उपयोग नहीं करता है this। यदि कोई Math.maxऐसा उपयोग करता है जो उसे ओवरराइड करता है this, तो उन्होंने उसके व्यवहार का उल्लंघन किया है और आपको उन पर तेज वस्तु फेंकनी चाहिए। आपको उस संभावना के आस-पास कोड नहीं करना चाहिए जितना आप किसी के द्वारा स्वैप किए गए Math.maxऔर Math.minलुलज़ के लिए संभावना से अधिक कोड करेंगे ।
मार्क अमेरी

15

इसे करने का एक और तरीका:

var arrayMax = Function.prototype.apply.bind(Math.max, null);

उपयोग:

var max = arrayMax([2, 5, 1]);

क्या कोई समझा सकता है कि यह कैसे काम करता है? यह सुंदर डोप है। क्या मेरी समझ सही है: arrayMax एक फ़ंक्शन है और हम इसके प्रोटोटाइप की संपत्ति के लिए कुछ बांधते हैं? यह क्या है। आवेदन करें और क्या प्रत्येक प्रोटोटाइप में यह है?
सैम

: आप की जाँच कर सकते हैं benalman.com/news/2012/09/partial-application-in-javascript
sbr

14

वैकल्पिक तरीके


Math.minऔर Math.maxतरीकों दोनों पुनरावर्ती संचालन जे एस इंजन के कॉल स्टैक में जोड़ा जा रहा है कि, और सबसे अधिक संभावना कर रहे हैं दुर्घटना एक सरणी है कि मदों की बड़ी संख्या में शामिल
(अधिक ~ 10⁷ आइटम से, उपयोगकर्ता के ब्राउज़र पर निर्भर करता है)।

Math.max (... सरणी (1000000) .keys ());

अनक्रेन्डेड रेंज: अधिकतम कॉल स्टैक आकार को पार कर गया

इसके बजाय, कुछ का उपयोग करें:

arr.reduce((max, val) => max > val ? max : val, arr[0])

या बेहतर रन-टाइम के साथ:

function maxValue(arr) {
  let max = arr[0];

  for (let val of arr) {
    if (val > max) {
      max = val;
    }
  }
  return max;
}

या न्यूनतम और अधिकतम दोनों प्राप्त करने के लिए:

function getMinMax(arr) {
  return arr.reduce(({min, max}, v) => ({
    min: min < v ? min : v,
    max: max > v ? max : v,
  }), { min: arr[0], max: arr[0] });
}

या बेहतर रन-टाइम के साथ *:

function getMinMax(arr) {
  let min = arr[0];
  let max = arr[0];
  let i = arr.length;

  while (i--) {
    min = arr[i] < min ? arr[i] : min;
    max = arr[i] > max ? arr[i] : max;
  }
  return { min, max };
}

* 1,000,000 वस्तुओं के साथ परीक्षण किया गया:
केवल एक संदर्भ के लिए, केवल 4.32ms के साथ 1 फ़ंक्शन रन-टाइम (मेरी मशीन पर) 15.84ms बनाम 2nd फ़ंक्शन था।


13

यह आपके उद्देश्यों के अनुरूप हो सकता है।

Array.prototype.min = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.min);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

Array.prototype.max = function(comparer) {

    if (this.length === 0) return null;
    if (this.length === 1) return this[0];

    comparer = (comparer || Math.max);

    var v = this[0];
    for (var i = 1; i < this.length; i++) {
        v = comparer(this[i], v);    
    }

    return v;
}

आपको अपनी वी को 'इस [0] के साथ इनिशियलाइज़ करना चाहिए अगर कोई संख्या 0 से छोटी नहीं है
jasonmw

क्या comparerकुछ विशिष्ट दायरे में बुलाया जाना चाहिए? क्योंकि जैसा कि यह संदर्भ है this[index]जो undefinedहर समय होता है।
Roatin Marth

फिक्स्ड, मैं हमेशा फंक्शन लेवल स्कूपिंग के बारे में भूल जाता हूं।
ChaosPandion

ओह अब, अब @Ionut G. Stan उसी "गलत संदर्भ" तर्क के लिए आपकी आलोचना करेंगे, जैसा उन्होंने मुझसे किया था, क्योंकि आपकी डिफ़ॉल्ट तुलना ( Math.xxx) वैश्विक दायरे में चल रही होगी ...
Roatin Marth

यह सच हो सकता है, लेकिन नए फ़ंक्शन हस्ताक्षर की आवश्यकता नहीं है क्योंकि इसमें उन 2 वस्तुओं की तुलना की जाती है जिनकी तुलना करने की आवश्यकता है।
चोसपंडियन 19


12

मुझे आश्चर्य है कि कोई भी कम किए गए फ़ंक्शन का उल्लेख नहीं करता है।

var arr = [1, 10, 5, 11, 2]

var b = arr.reduce(function(previous,current){ 
                      return previous > current ? previous:current
                   });

b => 11
arr => [1, 10, 5, 11, 2]

जागरूक रहें: कम करें () IE9 से समर्थित है, developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
पॉल गोबी

1
मैं क्रोमियम के वर्तमान संस्करण में इसका उपयोग नहीं कर सकता।
PJSCopeland में

9

बड़े सरणियों (~ 10⁷ तत्वों) के लिए, Math.minऔर Math.maxनोड में एक रेंजइयर (अधिकतम कॉल स्टैक आकार को पार कर गया) की खरीद करता है।

बड़े सरणियों के लिए, एक त्वरित और गंदा समाधान है:

Array.prototype.min = function() {
    var r = this[0];
    this.forEach(function(v,i,a){if (v<r) r=v;});
    return r;
};

8

मेरे पास एक ही समस्या थी, मुझे एक सरणी के न्यूनतम और अधिकतम मूल्यों को प्राप्त करने की आवश्यकता थी और, मेरे आश्चर्य के लिए, सरणियों के लिए कोई अंतर्निहित कार्य नहीं थे। बहुत पढ़ने के बाद, मैंने खुद "टॉप 3" समाधानों का परीक्षण करने का फैसला किया:

  1. असतत समाधान: वर्तमान अधिकतम और / या न्यूनतम मूल्य के खिलाफ सरणी के हर तत्व की जांच करने के लिए एक लूप;
  2. APPLY समाधान: सरणी को Math.max और / या Math.min आंतरिक कार्यों पर भेजकर (null, array) का उपयोग करके भेजना;
  3. REDUCE समाधान: कम (फ़ंक्शन) का उपयोग करके सरणी के प्रत्येक तत्व के खिलाफ एक चेक का पुनरावर्तन करना।

परीक्षण कोड यह था:

function GetMaxDISCRETE(A)
{   var MaxX=A[0];

    for (var X=0;X<A.length;X++)
        if (MaxX<A[X])
            MaxX=A[X];

    return MaxX;
}

function GetMaxAPPLY(A)
{   return Math.max.apply(null,A);
}

function GetMaxREDUCE(A)
{   return A.reduce(function(p,c)
    {   return p>c?p:c;
    });
}

सरणी A को 100,000 यादृच्छिक पूर्णांक संख्याओं से भरा गया था, प्रत्येक फ़ंक्शन को विंडोज विस्टा के साथ इंटेल पेंटियम 4 2.99GHz डेस्कटॉप पर मोज़िला फ़ायरफ़ॉक्स 28.0 पर 10,000 बार निष्पादित किया गया था। प्रदर्शन, समय () फ़ंक्शन द्वारा पुनर्प्राप्त किए गए समय सेकंड में हैं। परिणाम ये थे, 3 भिन्नात्मक अंक और मानक विचलन:

  1. असतत समाधान: माध्य = 0.161s, sd = 0.078
  2. APPLY समाधान: माध्य = 3.571s, एसडी = 0.487
  3. REDUCE समाधान: माध्य = 0.350 s, sd = 0.044

असतत समाधान की तुलना में REDUCE समाधान 117% धीमा था। APPLY समाधान असतत समाधान की तुलना में 2,118% धीमा था। इसके अलावा, जैसा कि पीटर ने देखा, यह बड़े सरणियों (लगभग 1,000,000 से अधिक तत्वों) के लिए काम नहीं करता है।

इसके अलावा, परीक्षणों को पूरा करने के लिए, मैंने इस विस्तारित असतत कोड का परीक्षण किया:

var MaxX=A[0],MinX=A[0];

for (var X=0;X<A.length;X++)
{   if (MaxX<A[X])
        MaxX=A[X];
    if (MinX>A[X])
        MinX=A[X];
}

समय: मतलब = 0.218s, एसडी = 0.094

तो, यह साधारण असतत समाधान की तुलना में 35% धीमा है, लेकिन यह एक ही बार में अधिकतम और न्यूनतम दोनों मानों को प्राप्त करता है (कोई अन्य समाधान कम से कम दो बार लेगा जो उन्हें पुनः प्राप्त करने के लिए है)। एक बार जब ओपी को दोनों मानों की आवश्यकता होती है, तो असतत समाधान सबसे अच्छा विकल्प होगा (यहां तक ​​कि दो अलग-अलग कार्यों के लिए, एक अधिकतम की गणना के लिए और दूसरा न्यूनतम गणना के लिए, वे दूसरे सबसे अच्छा, REDUCE समाधान को बेहतर बनाएंगे)।


8

आप अपनी परियोजना में कहीं भी निम्नलिखित फ़ंक्शन का उपयोग कर सकते हैं:

function getMin(array){
    return Math.min.apply(Math,array);
}

function getMax(array){
    return Math.max.apply(Math,array);
}

और फिर आप सरणी पास करने वाले कार्यों को कॉल कर सकते हैं:

var myArray = [1,2,3,4,5,6,7];
var maximo = getMax(myArray); //return the highest number

8

निम्नलिखित कोड मेरे लिए काम करता है:

var valueList = [10,4,17,9,3];
var maxValue = valueList.reduce(function(a, b) { return Math.max(a, b); });
var minValue = valueList.reduce(function(a, b) { return Math.min(a, b); });

7

जैसे-जैसे आप जाते हैं, ट्रैक करते रहें।

var min = null;
var max = null;
for (var i = 0, len = arr.length; i < len; ++i)
{
    var elem = arr[i];
    if (min === null || min > elem) min = elem;
    if (max === null || max < elem) max = elem;
}
alert( "min = " + min + ", max = " + max );

यह मिन / अधिकतम नल को छोड़ देगा यदि सरणी में कोई तत्व नहीं हैं। यदि सरणी में कोई तत्व हैं, तो एक पास में अधिकतम और अधिकतम सेट करेंगे

आप rangeपुन: उपयोग की अनुमति देने और पठनीयता में सुधार करने के लिए उपरोक्त विधि का उपयोग करके एरे का विस्तार भी कर सकते हैं । पर एक काम बेला देखें http://jsfiddle.net/9C9fU/

Array.prototype.range = function() {

    var min = null,
        max = null,
        i, len;

    for (i = 0, len = this.length; i < len; ++i)
    {
        var elem = this[i];
        if (min === null || min > elem) min = elem;
        if (max === null || max < elem) max = elem;
    }

    return { min: min, max: max }
};

इसके समान इस्तेमाल किया

var arr = [3, 9, 22, -7, 44, 18, 7, 9, 15];

var range = arr.range();

console.log(range.min);
console.log(range.max);

@JordanDillonChapian मैं सहमत हूँ, लेकिन यह एक rangeफ़ंक्शन को विस्तारित करने के लिए तुच्छ होगा जो एक ही समय में अधिकतम और IMO दोनों को प्राप्त करने का सबसे अच्छा तरीका होगा - जैसा कि मैंने अपने उत्तर के लिए एक अद्यतन के साथ किया है।
तवान्फोसन

6

मैंने सोचा था कि मैं अपने सरल और आसान समाधान को साझा करूँगा।

मिनट के लिए:

var arr = [3, 4, 12, 1, 0, 5];
var min = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] < min) {
    min = arr[k];
  }
}
console.log("Min is: " + min);

और अधिकतम के लिए:

var arr = [3, 4, 12, 1, 0, 5];
var max = arr[0];
for (var k = 1; k < arr.length; k++) {
  if (arr[k] > max) {
    max = arr[k];
  }
}
console.log("Max is: " + max);



धन्यवाद। मैंने अपना जवाब बदल दिया।
आयनोट नेचुला

पुनरावृत्ति अभी भी गलत है (गैर-मौजूदा गुणों तक पहुंच)।
बरगी

क्या गलत है, मुझे कुछ भी गलत नहीं दिख रहा है। क्या आप कृपया एक उदाहरण प्रस्तुत कर सकते हैं?
इयोनुत नेचुला

1
अब के अनुसार संशोधित। आशा है कि मैंने आपको सही ढंग से समझा।
इयोनुत नेचुला

6

गणित फ़ंक्शन का अधिकतम और न्यूनतम का उपयोग करते हुए, उपयोग करने के लिए एक और फ़ंक्शन सॉर्ट () के फ़ंक्शन में बनाया गया है: यहां हम जाते हैं

const nums = [12, 67, 58, 30].sort((x, y) => 
x -  y)
let max = nums[0]
let min = nums[nums.length -1]

5

सरल सामान, वास्तव में।

var arr = [10,20,30,40];
arr.max = function() { return  Math.max.apply(Math, this); }; //attach max funct
arr.min = function() { return  Math.min.apply(Math, this); }; //attach min funct

alert("min: " + arr.min() + " max: " + arr.max());

5

यहाँ एक तरह की वस्तुओं से अधिकतम मूल्य प्राप्त करने का तरीका है। एक प्रतिलिपि बनाएँ (स्लाइस के साथ), फिर प्रतिलिपि को अवरोही क्रम में सॉर्ट करें और पहले आइटम को पकड़ो।

var myArray = [
    {"ID": 1, "Cost": 200},
    {"ID": 2, "Cost": 1000},
    {"ID": 3, "Cost": 50},
    {"ID": 4, "Cost": 500}
]

maxsort = myArray.slice(0).sort(function(a, b) { return b.ID - a.ID })[0].ID; 

5

का उपयोग कर Math.max()याMath.min()

Math.max(10, 20);   //  20
Math.min(-10, -20); // -20

निम्नलिखित फ़ंक्शन Function.prototype.apply()एक संख्यात्मक सरणी में अधिकतम तत्व को खोजने के लिए उपयोग करता है। getMaxOfArray([1, 2, 3])के बराबर है Math.max(1, 2, 3), लेकिन आप getMaxOfArray()किसी भी आकार के प्रोग्रामेटिक रूप से निर्मित सरणियों पर उपयोग कर सकते हैं ।

function getMaxOfArray(numArray) {
  return Math.max.apply(null, numArray);
}

या नए प्रसार ऑपरेटर के साथ, एक सरणी का अधिकतम प्राप्त करना बहुत आसान हो जाता है।

var arr = [1, 2, 3];
var max = Math.max(...arr); // 3
var min = Math.min(...arr); // 1

4

यदि आप प्रोटोएप का उपयोग कर रहे हैं, तो ChaosPandion का समाधान काम करता है। यदि नहीं, तो इस पर विचार करें:

Array.max = function( array ){
    return Math.max.apply( Math, array );
};

Array.min = function( array ){
    return Math.min.apply( Math, array );
};

यदि कोई सरणी मान पूर्णांक नहीं है तो उपरोक्त NaN लौटाएगा ताकि आपको उससे बचने के लिए कुछ कार्यक्षमता का निर्माण करना चाहिए। अन्यथा यह काम करेगा।


jeerose, आपके पास (गणित, यह) आंदोलनकारियों के रूप में क्यों है जब रोहिन मार्थ के पास केवल (शून्य, यह) है?
हन्कह्व

@ हंक: मेरी टिप्पणी पर अपनी प्रतिक्रिया के लिए मेरी प्रतिक्रिया देखें।

1
मुझे समझ नहीं आ रहा है कि "यदि आप प्रोटॉयपे का उपयोग कर रहे हैं तो ChaosPandion का समाधान काम करता है" से आपका क्या मतलब है। आपका समाधान अलग कैसे है, सिवाय आप Mathऑब्जेक्ट को संदर्भ के रूप में उपयोग कर रहे हैं ?
आयनू जी स्टेन

क्षमा करें, मेरा मतलब है कि यदि आप प्रोटोटाइप का विस्तार करते हैं तो आपका काम होगा। क्षमा याचना।
जय

तो जो बेहतर है, जीरो या कैओसपांडियन का?
हनक

3

यदि आप पुस्तकालय का उपयोग करते हैं शुगर काहैं। आप सुझाव देते हैं, तो आप arr.min () और arr.max () लिख सकतेहैं। आप गैर-संख्यात्मक सरणियों से न्यूनतम और अधिकतम मान भी प्राप्त कर सकते हैं।

न्यूनतम (नक्शा, सभी = गलत) सरणी में तत्व को सबसे कम मान देता है। मानचित्र एक फ़ंक्शन की जाँच करने के लिए एक मानचित्रण या एक शॉर्टकट के रूप में एक स्ट्रिंग अभिनय हो सकता है। यदि सब सही है, तो किसी सरणी में सभी न्यूनतम मान वापस कर देंगे।

अधिकतम (नक्शा, सभी = गलत) सरणी में तत्व को सबसे बड़ा मान देता है। मानचित्र एक फ़ंक्शन की जाँच करने के लिए एक मानचित्रण या एक शॉर्टकट के रूप में एक स्ट्रिंग अभिनय हो सकता है। यदि सब सच है, तो एक सरणी में सभी अधिकतम मान लौटाएंगे।

उदाहरण:

[1,2,3].min() == 1
['fee','fo','fum'].min('length') == "fo"
['fee','fo','fum'].min('length', true) == ["fo"]
['fee','fo','fum'].min(function(n) { return n.length; }); == "fo"
[{a:3,a:2}].min(function(n) { return n['a']; }) == {"a":2}
['fee','fo','fum'].max('length', true) == ["fee","fum"]

लो-डैश और अंडरस्कोर.जैब जैसी लाइब्रेरी भी इसी तरह के शक्तिशाली मिन और अधिकतम कार्य प्रदान करती हैं:

लो-डैश से उदाहरण:

_.max([4, 2, 8, 6]) == 8
var characters = [
  { 'name': 'barney', 'age': 36 },
  { 'name': 'fred',   'age': 40 }
];
_.max(characters, function(chr) { return chr.age; }) == { 'name': 'fred', 'age': 40 }

3
let arr = [2,5,3,5,6,7,1];

let max = Math.max(...arr); // 7
let min = Math.min(...arr); // 1

2
यह समाधान पहले से ही इस प्रश्न के कई अन्य उत्तरदाताओं द्वारा प्रदान किया गया है। आपका जवाब क्या जोड़ता है?
निक

3

प्रयत्न

let max= a=> a.reduce((m,x)=> m>x ? m:x);
let min= a=> a.reduce((m,x)=> m<x ? m:x);

Math.min / max (+ लागू) के लिए हमें त्रुटि मिलती है:

अधिकतम कॉल स्टैक का आकार पार हो गया (Chrome 74.0.3729.131)

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