Reputation: 367
With the following array:
arrOfOranges =
[{ "kerp": "thisThing", "time": "@ rocks 3"},
{ "kerp": "otherThing", "green": "blah"},
{ "kerp": "thisThing", "time": "(countriesToTheStart ^"},
{ "kerp": "anotherThing", "yellow": "row row"},
{ "kerp": "anotherThing", "yellow": "rigorous"},
{ "kerp": "thisThing", "time": ",,,,"}]
Each item has the following permanent structure:
[{kerp: ''}] which can be one of 3 values: thisThing, otherThing and anotherThing. And the other key for each object depends on the value of 'kerp'.
If kerp: 'thisThing' then the other key is 'time'. => { "kerp": "thisThing", "time": ""},
If kerp: 'otherThing' then the other key is 'green'. => { "kerp": "otherThing", "green": ""},
If kerp: 'anotherThing' then the other key is 'yellow'. => { "kerp": "anotherThing", "yellow": ""},
I want to get the last item in the array with 'kerp': 'thisThing'. However, the associated value of the 'time' key must contain a letter.
For example in the above array the last item in the array has 'kerp': 'thisThing', however 'time' does not contain a letter.
So I need to get this item from arrOfOranges where it's the last item in the array with kerp: thisThing and time with letters in the value:
{"kerp": "thisThing", "time": "(countriesToTheStart ^"}
Here is what I have so far:
if (arrOfOranges.filter(a=>a.kerp === "thisThing")) {
// this is just a eay to check if the array contains letters
if(arrOfOranges.time.match(/[\w]+/g)) {
return arrOfOranges.slice(-1)[0];
}
}
However it doesn't work as intended. How would I be able to do this?
Upvotes: 0
Views: 57
Reputation: 50684
You can reverse your arrOfOranges
using .reverse()
and then use .find()
on that reversed array. The find method will return the first object that the callback returns true
for. Below, I've made it return true for when the time
key contains a word-character \w
and when the kerp
key is equal to "thisThing"
. Note that I've used .slice()
before calling .reverse()
, as reverse will modify arrOfOranges
in place, which can be prevented by making a copy of the array first:
const arrOfOranges = [{ "kerp": "thisThing", "time": "@ rocks 3"}, { "kerp": "otherThing", "green": "blah"}, { "kerp": "thisThing", "time": "(countriesToTheStart ^"}, { "kerp": "anotherThing", "yellow": "row row"}, { "kerp": "anotherThing", "yellow": "rigorous"}, { "kerp": "thisThing", "time": ",,,,"}];
const search = {kerp: "thisThing", key: "time"};
const res = arrOfOranges.slice().reverse().find(
obj => obj.kerp === search.kerp && /\w/.test(obj[search.key])
);
console.log(res);
If you need a slightly more efficient approach, you can use a standard for loop to iterate backwards through your array:
const arrOfOranges = [{ "kerp": "thisThing", "time": "@ rocks 3"}, { "kerp": "otherThing", "green": "blah"}, { "kerp": "thisThing", "time": "(countriesToTheStart ^"}, { "kerp": "anotherThing", "yellow": "row row"}, { "kerp": "anotherThing", "yellow": "rigorous"}, { "kerp": "thisThing", "time": ",,,,"}];
const search = {kerp: "thisThing", key: "time"};
function findObj(data, search) {
for(let i = data.length-1; i >= 0; i--) {
const curr = data[i];
if(curr.kerp === search.kerp && /\w/.test(curr[search.key]))
return curr;
}
}
console.log(findObj(arrOfOranges, search));
Upvotes: 1
Reputation: 1116
You need to keep the check inside the filter.
const arrOfOranges = [
{ "kerp": "thisThing", "time": "@ rocks 3"},
{ "kerp": "otherThing", "green": "blah"},
{ "kerp": "thisThing", "time": "(countriesToTheStart ^"},
{ "kerp": "anotherThing", "yellow": "row row"},
{ "kerp": "anotherThing", "yellow": "rigorous"},
{ "kerp": "thisThing", "time": ",,,,"}
]
const result = arrOfOranges.filter(orange => orange.kerp === "thisThing" && orange.time.match(/[\w]+/g));
console.log(result);
Upvotes: 2