1

How do I filter an array two give me the subset created by overlap of two ranges?

For example, suppose Here's my array with a bunch of objects:

const list = [{
    id: 1,
    price: "10",
    weight: "19.45"
  },{
    id: 2,
    price: "14",
    weight: "27.8"
  },{
    id: 3,
    price: "45",
    weight: "65.7"
  },{
    id: 4,
    price: "37",
    weight: "120.5"
  },{
    id: 5,
    price: "65",
    weight: "26.9"
  },{
    id: 6,
    price: "120",
    weight: "19.3"
  },{
    id: 7,
    price: "20",
    weight: "45.7"
  }]

Now I want to filter the above array of objects based on a range for two parameters price and weight.

let range = {
    startPrice: 15,
    endPrice: 60,
    startWeight: 22.0,
    endWeight: 70.5,
  }

I want to filter my list with these range parameters which will return me an array with a subset of objects satisfying both the filter ranges. Hence, the output array should be:

filtered = [{
    id: 3,
    price: "45",
    weight: "65.7"
  },{
    id: 7,
    price: "20",
    weight: "45.7"
  }]

Because items with id: 3 and id: 5 satisfy the subset of both of the two ranges. How should my list.filter() function look like? Any help is greatly appreciated, thank you.

4
  • What did you try? Commented Sep 20, 2020 at 10:53
  • What do you think it should look like? Filter takes a function and should return true/false. Commented Sep 20, 2020 at 10:53
  • @evolutionxbox Yes, well but how do you return the subset? I'm comparing from a subset of two params. Commented Sep 20, 2020 at 11:22
  • I’m not sure what you mean. The output of filter returns a subset. Commented Sep 20, 2020 at 11:24

2 Answers 2

1

Note: I've used parseFloat because values are stored as a String. There are other ways to get a Number out of a String.

var list = [{"id":1,"price":"10","weight":"19.45"},{"id":2,"price":"14","weight":"27.8"},{"id":3,"price":"45","weight":"65.7"},{"id":4,"price":"37","weight":"120.5"},{"id":5,"price":"65","weight":"26.9"},{"id":6,"price":"120","weight":"19.3"},{"id":7,"price":"20","weight":"45.7"}];
var range = {
  startPrice: 15,
  endPrice: 60,
  startWeight: 22.0,
  endWeight: 70.5
};

var filtered=list.filter(
  element=> {
    var elementprice=parseFloat(element.price);
    var elementweight=parseFloat(element.weight);
    if(
      elementprice>=range.startPrice &&
      elementprice<=range.endPrice &&
      elementweight>=range.startWeight &&
      elementweight<=range.endWeight
    ) {
      return true;
    }
    return false;
  }
);
console.log(filtered);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Sign up to request clarification or add additional context in comments.

4 Comments

Filter is much simpler than a reduce
@mplungjan, do you know what is more efficient: filter(item=>(condition1 && condition2 && condition3 && condition4)), or filter(item=>condition1).filter(item=>condition2).filter(item=>condition3).filter(item=>condition4)? Say, huge arrays vs tiny, memory, speed, other things that I didn't think of yet?
It does not matter for a few hundred items, but why change to filter? Now your code is the same as mine. It was just a comment
Also no need to use an if when a filter uses a boolean See my answer for the simplest implementation
1

You mean 3 and 7

Also you need to either remove the quotes or cast to number. Note a filter will expect a true or false to a Boolean test is enough. No if or else needed

const list = [{ id: 1, price: "10", weight: "19.45" }, { id: 2, price: "14", weight: "27.8" }, { id: 3, price: "45", weight: "65.7" }, { id: 4, price: "37", weight: "120.5" }, { id: 5, price: "65", weight: "26.9" }, { id: 6, price: "120", weight: "19.3" }, { id: 7, price: "20", weight: "45.7" }];
 let range = { startPrice: 15, endPrice: 60, startWeight: 22.0, endWeight: 70.5, }

const res = list.filter(item => 
  +item.price >= range.startPrice && 
  +item.price <= range.endPrice &&
  +item.weight >= range.startWeight &&  
  +item.weight <= range.endWeight);
console.log(res);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.