0

I just want to pull out an array element based on a condition.

I tried Underscore.js methods like _.filter and _.where methods, but I cannot get the desired output.

For more clarity, I don't want a car object where the price is > 80.

I tried with the code below and got an empty array back:

var carsArray = [{
    "name": "Record1",
    "bookings": [{
        "price": 50,
        "actualPrice": 70,
    }]
}, {
    "name": "Record2",
    "bookings": [{
        "price": 60,
        "actualPrice": 100,
    }]
}, {
    "name": "Record3",
    "bookings": [{
        "price": 100,
        "actualPrice": 110,
    }]
}];

var availableCars = _.filter(carsArray, function (items) {
    return _.filter(items, function (cars) {
        return(cars.price <= 80);
    });
});
1
  • bookings is an array, what happens if you have more than one object there? Which one is the price? Commented Feb 18, 2016 at 14:05

5 Answers 5

1

here's how to do it with underscorejs

var availableCars = _.filter(carsArray, function(car) {
    return _.any(car.bookings, function(booking) {
        return booking.price <= 80; 
    });
});

and here's how to do it in es6

var availableCars = carsArray.filter(car => car.bookings.some(booking => booking.price <= 80));

this ofcourse is if there are multiple bookings possible in a car and at least 1 booking is <= 80 buckeronies

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

3 Comments

Happy to help out! Do note: Array.prototype.filter and Array.prototype.some can also be used without ES6 and are supported since IE9. You could use them without the array functions! carsArray.filter(function(car) { return car.bookings.some(function(booking) { return booking.price <= 80; }); });
...and what's the difference between using _.any and _.every in Underscore? In my case, I tested both methods to filter Car objects and they populate the same output.
because you are filtering against 1 'booking'. Try filtering against 2: one booking with 60, one with 110. Any and Every work as the names imply: return true if any or return true if every object matches.
1

I think what you want is this:

var availableCars = _.filter(carsArray, function(car){
  return _.every(car.bookings, function(booking) {
    return booking.price <= 80;
  });
});

I'm assuming each car can have more than one booking and that you want a car only if none of its booking was more than 80.

Comments

1

For multiple elements in the bookings array

If there are multiple elements in the bookings array and to check if any of the element satisfies the condition Array#some can be used.

carsArray.filter(car => car.bookings.some(booking => booking.price <= 80));

To check if all the car booking prices are below 80 Array#every can be used.

carsArray.filter(car => car.bookings.every(booking => booking.price <= 80));

Live Demo:

var carsArray = [{
    "name": "Record1",
    "bookings": [{
        "price": 50,
        "actualPrice": 70,
    }, {
        "price": 40,
        "actualPrice": 70
    }]
}, {
    "name": "Record2",
    "bookings": [{
        "price": 60,
        "actualPrice": 100,
    }, {
        "price": 90,
        "actualPrice": 160
    }]
}, {
    "name": "Record3",
    "bookings": [{
        "price": 100,
        "actualPrice": 110,
    }, {
        "price": 120,
        "actualPrice": 200
    }]
}];

var atLeastOne = carsArray.filter(car => car.bookings.some(booking => booking.price <= 80));
var allCars = carsArray.filter(car => car.bookings.every(booking => booking.price <= 80));

document.getElementById('some').innerHTML = JSON.stringify(atLeastOne, 0, 4);
document.getElementById('every').innerHTML = JSON.stringify(allCars, 0, 4);
<strong>For any of the car bookings less than or equal to 80</strong>
<pre id="some"></pre>

<hr />
<strong>For all of the car bookings less than or equal to 80</strong>
<pre id="every"></pre>


For single element in bookings array

You can use JavaScript Array#filter with Arrow function as follow.

carsArray.filter(car => car.bookings[0].price <= 80);

var carsArray = [{
    "name": "Record1",
    "bookings": [{
        "price": 50,
        "actualPrice": 70,
    }]
}, {
    "name": "Record2",
    "bookings": [{
        "price": 60,
        "actualPrice": 100,
    }]
}, {
    "name": "Record3",
    "bookings": [{
        "price": 100,
        "actualPrice": 110,
    }]
}];

var filteredArr = carsArray.filter(car => car.bookings[0].price <= 80);

console.log(filteredArr);
document.getElementById('result').innerHTML = JSON.stringify(filteredArr, 0, 4);
<pre id="result"></pre>


If there is only a single element in the bookings array, the format of the data can be changed as

var carsArray = [{
    "name": "Record1",
    "bookings": {
        "price": 50,
        "actualPrice": 70,
    }
}, {
    "name": "Record2",
    "bookings": {
        "price": 60,
        "actualPrice": 100,
    }
}, {
    "name": "Record3",
    "bookings": {
        "price": 100,
        "actualPrice": 110,
    }
}];

var filteredArr = carsArray.filter(car => car.bookings.price <= 80);

1 Comment

Hello Tushar,There will be more than one entry in bookings array.
1

Thought I'd chip in with something that is closer to the requirement

I don't want a car object where the price is > 80

function expensiveBooking(booking){
    return booking.price > 80;
}

function carHasExpensiveBooking(car){
    return _.some(car.bookings, expensiveBooking);
}

var result = _.reject(carsArray, carHasExpensiveBooking);

Comments

0

Try this:

var availableCars = _.filter(carsArray, function(item){
    return (item.bookings.price <= 80);
    });
});

1 Comment

Still the array is empty but it works with _.every / _.any methods

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.