snowfrogdev
snowfrogdev

Reputation: 6873

In Javascript how to find the object in an array that has the highest valued specific property while meeting some conditions

There is an array called householdArray populated with objects that have two properties: the first one is isSelling, the value of which is either trueor false. The second one is askingPricethe value of which is a number. There is another object called buyer that has a budget property with a numerical value.

How do I find, out of all the objects that have isSelling === true in the householdArray which one has the highest askingPricethat is within buyer's budget?

Upvotes: 0

Views: 107

Answers (3)

Redu
Redu

Reputation: 26201

You can use filters and min max but i would do this job simply in one pass , in O(n) time by utilizing Array.prototype.reduce(). To encourage you using arrow functions I will show you first with the arrows then with conventional function implementation.

Please note that we use an object like {isSelling: true, askingPrice: 0} as initial value to the reduce operation.

var buyer = {budget:1000},
household = [{  isSelling: true,
              askingPrice: 500},
             {  isSelling: false,
              askingPrice: 500},
             {  isSelling: true,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: false,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 1200},
             {  isSelling: false,
              askingPrice: 690},
             {  isSelling: true,
              askingPrice: 890},
             {  isSelling: true,
              askingPrice: 1500},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: true,
              askingPrice: 900},
             {  isSelling: true,
              askingPrice: 990},
             {  isSelling: false,
              askingPrice: 990},
             {  isSelling: true,
              askingPrice: 670}
            ],
   result = household.reduce((p,c) => c.isSelling === true          &&
                                      c.askingPrice <= buyer.budget &&
                                      c.askingPrice > p.askingPrice ? c : p,{isSelling: true, askingPrice: 0});
console.log(result);

And now with a conventional function implementation

var buyer = {budget:1000},
household = [{  isSelling: true,
              askingPrice: 500},
             {  isSelling: false,
              askingPrice: 500},
             {  isSelling: true,
              askingPrice: 670},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: false,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 1200},
             {  isSelling: false,
              askingPrice: 690},
             {  isSelling: true,
              askingPrice: 890},
             {  isSelling: true,
              askingPrice: 1500},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: true,
              askingPrice: 900},
             {  isSelling: true,
              askingPrice: 990},
             {  isSelling: false,
              askingPrice: 990},
             {  isSelling: true,
              askingPrice: 1000}
            ],
   result = household.reduce(function(p,c){
                               return c.isSelling === true          &&
                                      c.askingPrice <= buyer.budget &&
                                      c.askingPrice > p.askingPrice ? c : p
                             },{isSelling: true, askingPrice: 0});
console.log(result);

And if you would like to get the index of the record that fits our condition you simply add the index argument to the callback of reduce and use an initial value of "0" as follows;

var buyer = {budget:1000},
household = [{  isSelling: false,
              askingPrice: 1500},
             {  isSelling: false,
              askingPrice: 500},
             {  isSelling: true,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 670},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: false,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 1200},
             {  isSelling: false,
              askingPrice: 690},
             {  isSelling: true,
              askingPrice: 890},
             {  isSelling: true,
              askingPrice: 1500},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: true,
              askingPrice: 900},
             {  isSelling: true,
              askingPrice: 990},
             {  isSelling: false,
              askingPrice: 990}
            ],
   result = household.reduce(function(p,c,i,a){
                               return  a[p].isSelling === false        ||
                                       a[p].askingPrice > buyer.budget ||
                                       c.isSelling === true            &&
                                       c.askingPrice <= buyer.budget   &&
                                       c.askingPrice > a[p].askingPrice ? i : p;  
                             },0);
result = household[result].isSelling === true && household[result].askingPrice <= buyer.budget ? result : -1;
console.log(result);

Upvotes: 2

Ronnie Smith
Ronnie Smith

Reputation: 18595

This is called filtering and sorting.

var buyer = {budget:1000};
var household = [{  isSelling: true,
              askingPrice: 500},
             {  isSelling: false,
              askingPrice: 500},
             {  isSelling: true,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: false,
              askingPrice: 1000},
             {  isSelling: true,
              askingPrice: 1200},
             {  isSelling: false,
              askingPrice: 690},
             {  isSelling: true,
              askingPrice: 890},
             {  isSelling: true,
              askingPrice: 1500},
             {  isSelling: true,
              askingPrice: 790},
             {  isSelling: true,
              askingPrice: 900},
             {  isSelling: true,
              askingPrice: 990},
             {  isSelling: false,
              askingPrice: 990},
             {  isSelling: true,
              askingPrice: 670}
            ];

function budgetFilter(obj) {
  if (obj.isSelling === true && obj.askingPrice <= buyer.budget) {
    return true;
  } else {
    return false;
  }
}

var result = household.filter(budgetFilter);
result.sort(function (a, b) {
  if (a.askingPrice < b.askingPrice) {
    return 1;
  }
  if (a.askingPrice > b.askingPrice) {
    return -1;
  }
  // a must be equal to b
  return 0;
});

console.log('Filtered Array\n', result[0]); 
//console.log('Filtered Array\n', result);  show sorted array

Upvotes: 0

chanoto89
chanoto89

Reputation: 241

You can find what you're looking for by filtering out those objects where isSelling === true and where the askingPrice is <= the buyer's budget. Then you can use Math.max.apply() on the array to find the object with the highest asking price within the budget. See below:

var buyer= {"budget": 700};

var householdArray = [{"isSelling": true, "askingPrice": 100}, {"isSelling": false, "askingPrice": 800}, {"isSelling": true, "askingPrice": 500}, {"isSelling": true, "askingPrice": 600}];

var qualifiedBudgets = householdArray.filter(x => x.isSelling && x.askingPrice <= buyer.budget);

//use map to get array of numbers representing the asking prices
var selectedArray = householdArray.find(f => f.askingPrice === Math.max.apply(null, qualifiedBudgets.map(x => x.askingPrice)));

//value should be the array with asking price of 600
console.log(selectedArray);

You can also chain it together too like:

var selectedArray= householdArray.find(f => f.askingPrice === Math.max.apply(null, householdArray.filter(x => x.isSelling && x.askingPrice <= buyer.budget).map(x => x.askingPrice)));

Upvotes: 1

Related Questions