2012-01-14 21 views
47

प्राप्त करने के लिए ऑब्जेक्ट्स के जावास्क्रिप्ट ऐरे की तुलना करें मेरे पास ऑब्जेक्ट्स की एक सरणी है और मैं उन ऑब्जेक्ट्स को किसी विशिष्ट ऑब्जेक्ट प्रॉपर्टी पर तुलना करना चाहता हूं। यहां मेरी सरणी है:न्यूनतम/अधिकतम

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

मैं विशेष रूप से "लागत" पर शून्य करना चाहता हूं और न्यूनतम और अधिकतम मूल्य प्राप्त करना चाहता हूं। मुझे एहसास है कि मैं केवल लागत मूल्यों को पकड़ सकता हूं और उन्हें जावास्क्रिप्ट सरणी में डाल सकता हूं और फिर Fast JavaScript Max/Min चला सकता हूं।

हालांकि मध्य में सरणी चरण को छोड़कर और ऑब्जेक्ट गुणों (इस मामले में "लागत") को सीधे छोड़कर ऐसा करने का कोई आसान तरीका है?

उत्तर

36

इस मामले में सबसे तेज़ तरीका सभी तत्वों के माध्यम से लूपिंग है, और इसकी तुलना अब तक उच्चतम/निम्नतम मूल्य से करें।

(एक सरणी बनाना, सरणी विधियों का आह्वान करना इस सरल ऑपरेशन के लिए अधिक है)।

// There's no real number bigger than plus Infinity 
var lowest = Number.POSITIVE_INFINITY; 
var highest = Number.NEGATIVE_INFINITY; 
var tmp; 
for (var i=myArray.length-1; i>=0; i--) { 
    tmp = myArray[i].Cost; 
    if (tmp < lowest) lowest = tmp; 
    if (tmp > highest) highest = tmp; 
} 
console.log(highest, lowest); 
+0

यह समझ में आता है, मैं बाहरी उच्च/निम्न संख्या के बजाय सरणी के अंदर डेटा की तुलना करने के बारे में सोचने के साथ अटक गया हूं। – firedrawndagger

+1

एकमात्र चीज जो मैं बदलूंगा वह सबसे कम और उच्चतम सेटिंग कम अनावश्यक है। मैं बल्कि एक कम समय लूप और 'न्यूनतम = उच्चतम = myArray [0]' सेट करें और फिर लूप को 1. –

+1

@ 32 बिटकिड अच्छा बिंदु पर शुरू करें। 'myArray [0] होना चाहिए। हालांकि, हालांकि। लेकिन, यदि कोई पहला तत्व नहीं है, तो एक त्रुटि फेंक दी जाएगी। इसलिए, एक अतिरिक्त जांच की आवश्यकता है, संभवतः छोटे प्रदर्शन को बढ़ावा देना पूर्ववत करना। –

17

sort का उपयोग करें, यदि आपको संशोधित सरणी की परवाह नहीं है।

myArray.sort(function (a, b) { 
    return a.Cost - b.Cost 
}) 

var min = myArray[0], 
    max = myArray[myArray.length - 1] 
+3

एक पूर्ण प्रकार न्यूनतम/अधिकतम खोजने का सबसे तेज़ तरीका नहीं है, लेकिन मुझे लगता है कि यह काम करेगा। –

+4

बस ध्यान रखें कि यह 'myArray' को संशोधित करेगा, जिसकी अपेक्षा नहीं की जा सकती है। – ziesemer

12

मुझे लगता है कि वास्तव में Rob W's answer सही (+1) है, लेकिन सिर्फ मनोरंजन के लिए: यदि आप "चालाक" बनना चाहता था, आप कुछ इस तरह कर सकता है:

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

function finder(cmp, arr, attr) { 
    var val = arr[0][attr]; 
    for(var i=1;i<arr.length;i++) { 
     val = cmp(val, arr[i][attr]) 
    } 
    return val; 
} 

alert(finder(Math.max, myArray, "Cost")); 
alert(finder(Math.min, myArray, "Cost")); 

या यदि आप एक गहरा आंतरिक संरचना था, तो आप एक छोटे से अधिक कार्यात्मक हो और निम्न कर सकता है:

var myArray = 
[ 
    {"ID": 1, "Cost": { "Wholesale":200, Retail: 250 }}, 
    {"ID": 2, "Cost": { "Wholesale":1000, Retail: 1010 }}, 
    {"ID": 3, "Cost": { "Wholesale":50, Retail: 300 }}, 
    {"ID": 4, "Cost": { "Wholesale":500, Retail: 1050 }} 
] 

function finder(cmp, arr, getter) { 
    var val = getter(arr[0]); 
    for(var i=1;i<arr.length;i++) { 
     val = cmp(val, getter(arr[i])) 
    } 
    return val; 
} 

alert(finder(Math.max, myArray, function(x) { return x.Cost.Wholesale; })); 
alert(finder(Math.min, myArray, function(x) { return x.Cost.Retail; })); 

ये कर सकते थे easi ly अधिक उपयोगी/विशिष्ट रूपों में curried हो।

+3

मैंने अपने समाधानों का बेंचमार्क किया है: http://jsperf.com/comparison-of-numbers। अपने कोड को अनुकूलित करने के बाद (बेंचमार्क देखें), दोनों विधियों का प्रदर्शन समान है। अनुकूलन के बिना, मेरी विधि 14x तेज है। –

+1

@RoBW ओह, मैं पूरी तरह से आपके संस्करण को * रास्ता * तेज होने की उम्मीद करता हूं, मैं केवल एक वैकल्पिक वास्तुकला कार्यान्वयन प्रदान कर रहा था। :) –

+0

@ 32 बिटकिड मुझे उम्मीद थी, लेकिन आश्चर्य की बात है कि, बेंचमार्क के टेस्ट केस 3 में देखा गया है कि विधि लगभग तेज (अनुकूलन के बाद) है। –

-1

एक और एक, Kennebec के जवाब देने के लिए समान है, लेकिन एक पंक्ति में सभी:

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

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

var arr = [1,4,2,6,88,22,344]; 

var max = Math.max.apply(Math, arr);// return 344 
var min = Math.min.apply(Math, arr);// return 1 
1
कुल संचालन (न्यूनतम, अधिकतम की तरह प्रदर्शन करने के लिए:

यह समाधान

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

    myArray.forEach(function (keyValue, index, myArray) { 
     if(index > 0) { 
     if(keyValue.Cost < lowestNumber){ 
      lowestNumber = keyValue.Cost; 
     } 
     if(keyValue.Cost > highestNumber) { 
      highestNumber = keyValue.Cost; 
     } 
     } 
    }); 
    console.log('lowest number' , lowestNumber); 
    console.log('highest Number' , highestNumber); 
74

को कम इस तरह सामान के लिए अच्छा है और अधिक बेहतर है औसत, आदि) में ऑब्जेक्ट की श्रृंखला पर है, और एक ही परिणाम देते हैं:

Array.prototype.hasMin = function(attrib) { 
    return this.reduce(function(prev, curr){ 
     return prev[attrib] < curr[attrib] ? prev : curr; 
    }); 
} 

अब आप कह सकते हैं:

myArray.reduce(function(prev, curr) { 
    return prev.Cost < curr.Cost ? prev : curr; 
}); 

आप प्यारा आप सरणी को यह संलग्न कर सकते हैं होना चाहते हैं:

myArray.hasMin('ID') // result: {"ID": 1, "Cost": 200} 
myArray.hasMin('Cost') // result: {"ID": 3, "Cost": 50} 
+7

मेरी राय में सबसे अच्छा जवाब।यह सरणी को संशोधित नहीं करता है और यह उत्तर से कहीं अधिक संक्षिप्त है जो कहता है "एक सरणी बनाना, इस सरल ऑपरेशन के लिए सरणी विधियों का आविष्कार करना अधिक है" –

+0

यह बड़े डेटासेट (30+ कॉलम/100k के प्रदर्शन के लिए बिल्कुल सही उत्तर है) पंक्तियाँ)। – cerd

+0

पहले भाग में एक गायब संश्लेषण है। – hhh

9

उपयोग Math कार्यों और मूल्यों आप map साथ चाहते बाहर बांधना।

यहाँ jsbin है:

https://jsbin.com/necosu/1/edit?js,console

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

    min = Math.min.apply(null, myArray.map(function(item) { 
    return item.Cost; 
    })), 
    max = Math.max.apply(null, myArray.map(function(item) { 
    return item.Cost; 
    })); 

console.log('min', min);//50 
console.log('max', max);//1000 

अद्यतन:

आप ES6 उपयोग करना चाहते हैं:

var min = Math.min.apply(null, myArray.map(item => item.Cost)), 
    max = Math.max.apply(null, myArray.map(item => item.Cost)); 
+3

स्प्रेड ऑपरेटर का उपयोग करते हुए ईएस 6 में, हमें अब 'लागू' की आवश्यकता नहीं है। बस कहें - 'Math.min (... myArray.map (o => o.Cost))' न्यूनतम और ढूंढने के लिए 'Math.max (... myArray.map (o => o.Cost)) 'अधिकतम खोजने के लिए। – Nitin

2

Array.prototype.reduce() का उपयोग करके आप तुलनित्र कार्यों में प्लग कर सकते हैं एक सरणी में न्यूनतम, अधिकतम, आदि आइटम निर्धारित करने के लिए।

var items = [ 
 
    { name : 'Apple', count : 3 }, 
 
    { name : 'Banana', count : 10 }, 
 
    { name : 'Orange', count : 2 }, 
 
    { name : 'Mango', count : 8 } 
 
]; 
 

 
function findBy(arr, key, comparatorFn) { 
 
    return arr.reduce(function(prev, curr, index, arr) { 
 
    return comparatorFn.call(arr, prev[key], curr[key]) ? prev : curr; 
 
    }); 
 
} 
 

 
function minComp(prev, curr) { 
 
    return prev < curr; 
 
} 
 

 
function maxComp(prev, curr) { 
 
    return prev > curr; 
 
} 
 

 
document.body.innerHTML = 'Min: ' + findBy(items, 'count', minComp).name + '<br />'; 
 
document.body.innerHTML += 'Max: ' + findBy(items, 'count', maxComp).name;

1

ट्रिस्टन रीड के जवाब पर जोड़ा जा रहा है (ES6 का उपयोग कर +), आप एक समारोह है कि एक कॉलबैक, जो ऑपरेटर आप prev और curr लिए लागू किया जा करना चाहते हैं शामिल होंगे स्वीकार करता है बना सकते हैं:

const compare = (arr, key, callback) => arr.reduce((prev, curr) => 
    (callback(prev[key], curr[key]) ? prev : curr), {})[key]; 

    // remove `[key]` to return the whole object 

तो आप बस इसे का उपयोग कर कह सकते हैं:

const costMin = compare(myArray, 'Cost', (a, b) => a < b); 
const costMax = compare(myArray, 'Cost', (a, b) => a > b); 

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

  • कोई संबंधित समस्या नहीं^_^