ন্যূনতম / সর্বোচ্চ পেতে জাভাস্ক্রিপ্ট অ্যারে অবজেক্টের তুলনা করুন Comp


99

আমার কাছে অবজেক্টগুলির একটি অ্যারে রয়েছে এবং আমি নির্দিষ্ট বস্তুর সম্পত্তিতে এই বিষয়গুলি তুলনা করতে চাই। এখানে আমার অ্যারে:

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

আমি বিশেষত "ব্যয়" শূন্য করতে চাই এবং একটি ন্যূনতম এবং সর্বাধিক মান পেতে চাই। আমি বুঝতে পেরেছি যে আমি কেবল ব্যয় মানগুলি ধরতে পারি এবং এগুলি একটি জাভাস্ক্রিপ্ট অ্যারেতে ঠেলে দিতে পারি এবং তারপরে দ্রুত জাভাস্ক্রিপ্ট সর্বোচ্চ / মিনিট চালাতে পারি ।

তবে মাঝখানে অ্যারে স্টেপটি বাইপাস করে এবং অবজেক্ট প্রোপার্টিটি (এই ক্ষেত্রে "ব্যয়") সরাসরি চলে গিয়ে কি করার সহজ উপায় আছে?

উত্তর:


55

এই ক্ষেত্রে, দ্রুততম উপায়টি সমস্ত উপাদানগুলির মধ্যে লুপিং করছে এবং এটিকে এখন পর্যন্ত সর্বোচ্চ / সর্বনিম্ন মানের সাথে তুলনা করে।

(একটি সাধারণ অ্যারে তৈরি করার জন্য একটি অ্যারে তৈরি করা হচ্ছে, অ্যারে পদ্ধতিগুলি চাওয়া হয়েছে ওভারকিল)।

 // 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);

এটি উপলব্ধি করে, আমি বাহ্যিক উচ্চ / নিম্ন সংখ্যার পরিবর্তে অ্যারের অভ্যন্তরে ডেটা তুলনা করার চিন্তাভাবনায় আটকে গিয়েছি।
19/01 এ 01

4
কেবলমাত্র আমি পরিবর্তন করতে চাই সেটি হ'ল সর্বনিম্ন এবং সর্বোচ্চটি কিছুটা রিডানড্যান্ট। আমি বরং lowest=highest=myArray[0]একবারে আরও একবার লুপ করব এবং সেট করব এবং তারপরে 1 এ লুপটি শুরু করব
জে হোমস

4
@ 32 বিটকিড ভাল পয়েন্ট হওয়া উচিত myArray[0].Cost, যদিও। তবে, যদি কোনও প্রথম উপাদান না থাকে তবে একটি ত্রুটি নিক্ষেপ করা হবে। সুতরাং, সম্ভবত ছোট সম্পাদনাকে উত্সাহিত করতে একটি অতিরিক্ত চেক প্রয়োজন।
রব ডাব্লু

4
@ উইল্ট হ্যাঁ, আরেকটি পরিবর্তনশীল বজায় রাখুন যা আপডেট হয়ে যায় যখন আপনি সর্বনিম্ন মান খুঁজে পাবেন, যেমন var lowestObject; for (...)এবংif (tmp < lowest) { lowestObject = myArray[i]; lowest = tmp; }
রব ডব্লু

4
ECMAScript 2015 (ES6) বের হওয়ার আগে এই উত্তরটি খুব পুরানো। ঠিক সময়ে ছিল, কিন্তু এখন যে উত্তর একটি ভাল বিকল্প।
এরিক পেট্রুসেলি

171

হ্রাস এই জাতীয় স্টাফের জন্য ভাল: সামগ্রীর ক্রিয়াকলাপগুলি (যেমন নূন্যতম, সর্বোচ্চ, গড় ইত্যাদি) সম্পাদন করতে এবং একটি ফলাফল প্রদান করে:

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

... বা আপনি ES6 ফাংশন সিনট্যাক্সের সাহায্যে অভ্যন্তরীণ ফাংশনটি সংজ্ঞায়িত করতে পারেন:

(prev, curr) => prev.Cost < curr.Cost ? prev : curr

আপনি যদি সুন্দর হতে চান তবে এটিকে অ্যারেতে সংযুক্ত করতে পারেন:

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

এখন আপনি কেবল বলতে পারেন:

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

দয়া করে নোট করুন যে আপনি যদি এটি ব্যবহার করার ইচ্ছা করেন তবে প্রতিটি পরিস্থিতির জন্য এটির পুরো চেক নেই। আপনি যদি আদিম ধরণের অ্যারে পাস করেন তবে এটি ব্যর্থ হবে। আপনি যদি এমন কোনও সম্পত্তি অনুসন্ধান করেন যা অস্তিত্বহীন, বা যদি সমস্ত বস্তুতে সেই সম্পত্তি না থাকে তবে আপনি শেষ উপাদানটি পাবেন। এই সংস্করণটি আরও কিছুটা বড়, তবে সেগুলি রয়েছে:

Array.prototype.hasMin = function(attrib) {
    const checker = (o, i) => typeof(o) === 'object' && o[i]
    return (this.length && this.reduce(function(prev, curr){
        const prevOk = checker(prev, attrib);
        const currOk = checker(curr, attrib);
        if (!prevOk && !currOk) return {};
        if (!prevOk) return curr;
        if (!currOk) return prev;
        return prev[attrib] < curr[attrib] ? prev : curr; 
    })) || null;
 }

16
আমার মতে সেরা উত্তর। এটি অ্যারের সংশোধন করে না এবং এর উত্তরের চেয়ে আরও সংক্ষিপ্ত সংখ্যায় যে উত্তর দেয় যে "অ্যারে তৈরি করা, অ্যারে পদ্ধতিগুলি চাওয়া এই সাধারণ অপারেশনের জন্য ওভারকিল"
জুলিয়ান মান

এটি বড় ডেটাসেটগুলির কার্য সম্পাদনের জন্য পরম সেরা উত্তর (30+ কলাম / 100 কিলো সারি)।

4
শুধু ভাবছি, যখন অ্যারের প্রথম উপাদানটি চেক কমাবেন তখন অপরিজ্ঞাত হবে না prev.Cost? বা এটি 0 হিসাবে আরম্ভ কি?
গ্রেডফক্স

4
ভালো কথা @ সাহেব। আমি সবেমাত্র সম্পাদনা করেছি তাই এটি ক্ষেত্রে বাতিল হবে।
ত্রিস্তান রেড

4
আমি অন্যান্য ইনপুটগুলির জন্য কিছু চেকও যুক্ত করেছি যা সমস্যার কারণ হতে পারে, অ-অবজেক্টগুলির মতো, বা যদি সেই সম্পত্তি কিছু বস্তু থেকে অনুপস্থিত ছিল। শেষ পর্যন্ত এটি আমার মনে হয় বেশিরভাগ ক্ষেত্রে একটু ভারী হয়ে উঠছে।
ত্রিস্তান রেড

27

sortআপনি যদি অ্যারেটি সংশোধন করছেন সে বিষয়ে যত্নশীল না হন তবে ব্যবহার করুন ।

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

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

4
একটি সম্পূর্ণ বাছাই কমপক্ষে / সর্বাধিক সন্ধান করার দ্রুততম উপায় নয় তবে আমার ধারণা এটি কার্যকর হবে।
জে. হোমস

4
এটি সচেতন হন যে এটি সংশোধন করবে myArray, যা আশা করা যায় না।
ziesemer

একটি অ্যারে বাছাই করা এটি ট্র্যাভার করার চেয়ে ধীর। জটিলতা বাছাই করুন O(nlog(n))O(n)
:,

20

Mathফাংশনগুলি ব্যবহার করুন এবং আপনি যে মানগুলি চান তা ছড়িয়ে দিনmap

এখানে জেসবিন:

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));

18
ES6 এ স্প্রেড অপারেটর ব্যবহার করে, আমাদের আর দরকার নেই apply। সহজভাবে বলুন - Math.min(...myArray.map(o => o.Cost))সর্বনিম্ন Math.max(...myArray.map(o => o.Cost))সন্ধানের জন্য এবং সর্বাধিক সন্ধান করার জন্য।
নিতিন

13

আমার মনে হয় রব ডাব্লু এর উত্তরটি সত্যই সঠিক (+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; }));

এগুলি আরও কার্যকর / নির্দিষ্ট আকারে সহজেই ক্রিট করা যায়।


4
আমি আমাদের সমাধান benchmarked করেছেন: jsperf.com/comparison-of-numbers । আপনার কোডটি অপ্টিমাইজ করার পরে (মানদণ্ডটি দেখুন), উভয় পদ্ধতির পারফরম্যান্স একই রকম। অপ্টিমাইজেশন ছাড়াই, আমার পদ্ধতিটি 14x দ্রুত।
রব ডব্লিউ

4
@RoBW উহু আমি সম্পূর্ণই আপনার সংস্করণ হতে আশা করবে উপায় দ্রুত, আমি শুধু একটি বিকল্প স্থাপত্য বাস্তবায়ন প্রদান করতে শুরু করে। :)
জে হোমস

@ 32 বিটকিড আমিও একই প্রত্যাশা করেছিলাম, তবে আশ্চর্যরূপে, পদ্ধতিটি প্রায় তত দ্রুত (অনুকূলকরণের পরে), বেঞ্চমার্কের পরীক্ষার ক্ষেত্রে case নং ক্ষেত্রে দেখা যায়।
রব ডাব্লু

4
@ রব ডাব্লু আমি সম্মত, আমি এটি আশা করতাম না। আমি কৌতূহলী. :) দেখানোর জন্য যায় যে আপনার সবসময় ধরে নেওয়া বদলে বেনমার্ক করা উচিত।
জে হোমস

@ রবডাব্লু কেবল স্পষ্ট করে বলতে গেলে, আমি মনে করি আরও ব্রাউজার ফলাফলের সাথে আপনার প্রয়োগটি ধারাবাহিকভাবে অপ্রচলিত এবং অনুকূলিত সংস্করণগুলিকে মারবে।
জে হোমস

6

সর্বোচ্চ

Math.max.apply(Math, myArray.map(a => a.Cost));

মিনিটের জন্য

Math.min.apply(Math, myArray.map(a => a.Cost));

5

চেষ্টা করুন ( aঅ্যারে, fতুলনা করার ক্ষেত্র)

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


4
এই উত্তরটি পছন্দ করুন, তাই কমপ্যাক্ট এবং সহজেই ব্যবহারযোগ্য।
ডিন

4

অ্যারে.প্রোটোটাইপ.ড্রেস () ব্যবহার করে আপনি কোনও অ্যারেতে ন্যূনতম, সর্বোচ্চ, ইত্যাদি আইটেম নির্ধারণ করতে তুলনামূলক ফাংশনগুলিতে প্লাগ করতে পারেন।

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;


4

ব্যবহার Math.minএবং Math.max:

var myArray = [
    { id: 1, cost: 200},
    { id: 2, cost: 1000},
    { id: 3, cost: 50},
    { id: 4, cost: 500}
]


var min = Math.min(...myArray.map(item => item.cost));
var max = Math.max(...myArray.map(item => item.cost));

console.log("min: " + min);
console.log("max: " + max);


2

এটি আরও ভাল সমাধান

    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);

2

ত্রিস্তান রিডের উত্তরের সাথে যুক্ত করা (+ এস 6 ব্যবহার করে) আপনি একটি ফাংশন তৈরি করতে পারেন যা কলব্যাক গ্রহণ করে, এতে অপারেটর থাকবে যা আপনি প্রয়োগ করতে চান 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);

2

এটি লোডাস minByএবং maxByফাংশন দিয়ে অর্জন করা যেতে পারে ।

লোডাশ minByএবং maxByডকুমেন্টেশন

_.minBy(array, [iteratee=_.identity])

_.maxBy(array, [iteratee=_.identity])

এই পদ্ধতিগুলি একটি পুনরাবৃত্তি গ্রহণ করে যা মানকে স্থান নির্ধারণ করে এমন মানদণ্ড তৈরি করতে অ্যারের প্রতিটি উপাদানকে অনুরোধ করে। পুনরাবৃত্তিকে একটি যুক্তি দিয়ে যুক্ত করা হয়: (মান)।

সমাধান

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

const minimumCostItem = _.minBy(myArray, "Cost");

console.log("Minimum cost item: ", minimumCostItem);

// Getting the maximum using a functional iteratee
const maximumCostItem = _.maxBy(myArray, function(entry) {
  return entry["Cost"];
});

console.log("Maximum cost item: ", maximumCostItem);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.15/lodash.js"></script>


0

আমরা দুটি পদ্ধতির মাধ্যমে সমস্যাটি সমাধান করতে পারি উভয় পদ্ধতি ইতিমধ্যে উপরে বর্ণিত হয়েছে তবে পারফরম্যান্স টেস্টটি এতটা পূরণ করে নি

1, নেটিভ জাভা-স্ক্রিপ্ট উপায়
2, প্রথমে সাজানো অবজেক্ট তারপর সাজানো অবজেক্ট থেকে সর্বনিম্ন সর্বোচ্চ পাওয়া সহজ

আমি উভয় উভয় পদ্ধতির কর্মক্ষমতা পরীক্ষা

আপনি সঞ্চালন এবং সঞ্চালন পরীক্ষা করতে পারেন ... শুভ কোডিং (:

//first approach 

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

var t1 = performance.now();;

let max=Math.max.apply(Math, myArray.map(i=>i.Cost))

let min=Math.min.apply(Math, myArray.map(i=>i.Cost))

var t2   = performance.now();;

console.log("native fuction took " + (t2 - t1) + " milliseconds.");

console.log("max Val:"+max)
console.log("min Val:"+min)

//  Second approach:


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

var s1 = performance.now();;
sortedArray=myArray.sort(sortFunc)


var minBySortArray = sortedArray[0],
    maxBySortArray = sortedArray[myArray.length - 1]
    
var s2   = performance.now();;
 console.log("sort funciton took  " + (s2 - s1) + " milliseconds.");  
console.log("max ValBySortArray :"+max)
console.log("min Val BySortArray:"+min)


0

সংক্ষিপ্ত, আধুনিক সমাধানের জন্য, reduceবর্তমানের সর্বনিম্ন এবং সর্বাধিক মানগুলি ট্র্যাক করে, অ্যারের উপরে একটি ক্রিয়া সঞ্চালন করা যেতে পারে , সুতরাং অ্যারেটি কেবল একবারে পুনরাবৃত্তি হয় (যা সর্বোত্তম) is

let [min, max] = myArray.reduce(([prevMin,prevMax], {Cost})=>
   [Math.min(prevMin, Cost), Math.max(prevMax, Cost)], [Infinity, -Infinity]);

ডেমো:


-2

আর একটি, কেনেবেকের জবাবের মতো, তবে সমস্ত এক লাইনে:

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

-2

পরিবর্তে ম্যাথ.ম্যাক্স / ম্যাথ.মিন ব্যবহার করতে আপনি বিল্ট-ইন অ্যারে অবজেক্টটি ব্যবহার করতে পারেন:

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
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.