Reputation: 321
There is an array of objects of this form:
const rows = [{name: "john", color: "blue", height: 177, weight: 82},
{name: "anna", color: "red", height: 167, weight: 62},
{name: "mike", color: "green", height: 181, weight: 78},
{name: "sue", color: "red", height: 164, weight: 57}];
I need to find the first element that satisfies a condition and use it in the ternary, something like:
{rows.find(a => a.color === "red" && a.name === "anna") ? ... : ... }
Is there a way to get the result from the condition into the middle ternary term? Like:
{rows.find(a => a.color === "red" && a.name === "anna") ? a.height * a.width : null }
Upvotes: 0
Views: 655
Reputation: 1074989
There's no one-liner for your example with (Actually, there is,¹ but...) You need to either search again (which will often be just fine, but...) or store the search result in a variable so you can use it twice.color
, width
, and height
.
It looks like you're using this in a JSX expression. Typically grab the things you can to locals prior to the expression, then use those locals:
const entry = rows.find(a => a.color === "red" && a.name === "anna");
const result = entry ? a.height * a.width : null;
// ...later in your JSX...
{result}
Another option if it's a common operation is to (as always) put it in a reusable function:
// Somewhere it can be reused:
function areaOfOptionalObject(obj) {
return obj ? obj.width * obj.height : null;
}
// In your JSX:
{areaOfOptionalObject(rows.find(a => a.color === "red" && a.name === "anna"))}
Where you draw the line is a judgement call. For instance, you might put the find
in the function:
// Somewhere it can be reused:
function areaOfMatchingObject(array, predicate) {
const obj = array.find(predicate);
return obj ? obj.width * obj.height : null;
}
// In your JSX:
{areaOfMatchingObject(rows, a => a.color === "red" && a.name === "anna")}
¹ The one-liner is:
{rows.filter(a => a.color === "red" && a.name === "anna").map(a => a.weight * a.height)[0] ?? null}
...but it fully traverses rows
(rather than stopping when it finds something), creates two unnecessary temporary arrays, and is a bit...awkward. Still, it works, and rows
probably isn't all that big and the temporary arrays aren't really a big deal.
Thanks @VLAZ for pointing out that filter
-> map
[0]
would do it!
Upvotes: 3
Reputation: 564
You can do this in this way:
const found = rows.find(a => a.color === "red" && a.name === "anna");
const res = found ? found.height * found.width : null;
Upvotes: 2