2

I have the following Array structure:

[{…}, {…}, {…}, {…}, {…}, {…}]

One of the object inside this array can look like this:

[
    {
        name: 'testing', 
        other: 'value',
        ratings: [{category : 'passives'} , {category : 'detractor'}]
    }, 
    {
        name: 'testing2', 
        other: 'value',
        ratings: [{category : 'detractor'}]
    }
]

I want to select all the objects inside the array that includes a rating with the category passive.

So with the above object the return value should look like:

[
    {
        name: 'testing', 
        other: 'value',
        ratings: [{category : 'passives'} , {category : 'detractor'}]
    }
]

The reason is because that's the only object in the array that has a ratings with the category of passive included.

I tried something like:

 const response = 'passives'
 const ape = object.filter(project => {
     return project.ratings.filter(item => {
         return item.category === response
     })
 })
5
  • 3
    Change the inner filter to some. Commented Aug 14, 2020 at 14:35
  • 1
    And what going wrong? Except you try compare 'passive' with 'passives' Commented Aug 14, 2020 at 14:35
  • @Darth sorry typo, not in my code tho. In this question Commented Aug 14, 2020 at 14:35
  • @PatrickRoberts I'll give it a try Commented Aug 14, 2020 at 14:36
  • @YevgenGorbunkov that should be contained in your answer, not in a comment that might potentially get deleted. Commented Aug 14, 2020 at 15:17

3 Answers 3

3

Even if your inner .filter() returns an empty array it is evaluated as truthy by outer .filter(), so it won't actually filter anything.

If you need to return boolean (true or false), based on whether nested array includes object having desired property value, Array.prototype.some() is a perfect choice

const src = [{name:'testing',other:'value',ratings:[{category:'passives'},{category:'detractor'}]},{name:'testing2',other:'value',ratings:[{category:'detractor'}]}],
    
      result = src.filter(({ratings}) => 
                ratings.some(({category}) => 
                  category == 'passives'))
    
console.log(result)
.as-console-wrapper{min-height:100%;}

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

1 Comment

this is perfect thank you
0

You could try this

const arr = [
  {
    name: "testing",
    other: "value",
    ratings: [{ category: "passives" }, { category: "detractor" }],
  },

  {
    name: "testing2",
    other: "value",
    ratings: [{ category: "detractor" }],
  },
]

const res = arr.filter((obj) =>
  obj.ratings.find((rating) => rating.category === "passives") !== undefined
)

console.log(res)

5 Comments

find is not idiomatic here, and only coincidentally works in this case. As a counter example, if each object had an array of booleans and you were searching for a value of false, this would not work. edit I see you added the !== undefined but my underlying point still stands, it's not idiomatic code.
@PatrickRoberts I have compared with undefined. Moreover, no his case not involving any false values, so consider counter examples here is some kind of over-engineering.
Using some() instead of find() !== undefined is not "over-engineering", it's plain-and-simple idiomatic, correct code.
what is considered incorrect here, even in his question he cited includes a rating with the category, so just have to make sure to have one is enough. Moreover, the object shape has nothing to deal with boolean value, so why bothers counter example here?
There's more to programming than just getting the code to work. If it doesn't correctly communicate the intent, it makes the code harder to maintain. I'll turn the question around and ask why you bother to choose less than the best available builtin method that's designed exactly for this purpose?
0

Here is the working example:

let arr = [
    {
        name : 'testing', 
        other: 'value',
        ratings : [{category : 'passives'} , {category : 'detractor'}]
    }, 

    {
        name : 'testing2', 
        other: 'value',
        ratings : [{category : 'detractor'}]
    }
];

const response = 'passives'
const ape = [];

arr.map(project => {
    const filtered = project.ratings.filter(item => item.category === response);
    if(filtered.length > 0) {
        ape.push(project);
    }
});

console.log(ape);

3 Comments

This is a completely inappropriate use of map.
You'd be much better off with Array.prototype.forEach() for simple looping
Or just using the idiomatic filter(), as was already the case...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.