1

I am fetching an array of objects as following :

const data =
  [ { id: 0, company: 'nike',   items: [{ id: 0, name: 'caret',        price: 100}] } 
  , { id: 1, company: 'adidas', items: [{ id: 1, name: 'mobile phone', price: 300}] } 
  ] 

I want to filter that array of objects by checking the value of the property "name" inside the items array if it is "Caret" or not. If yes, I want to return the same array of objects with all its content but filtered. Which means, it will filter out the object whose item's name is not caret. How can I achieve this in javascript?!

Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
Saif
  • 249
  • 5
  • 15

2 Answers2

2

I suppose you are looking for that ?

const data =
  [{ id: 0, company: 'nike',   items: [{ id: 0, name: 'caret',        price: 100}]}
  ,{ id: 1, company: 'adidas', items: [{ id: 1, name: 'mobile phone', price: 300}]}
  ] 

const filterName = (arr, name)=>arr.filter(el=>el.items.some(x=>x.name==name))

onlyCaret = filterName(data,'caret')

console.log( onlyCaret[0].company )  // nike
console.log( onlyCaret )   // row 0 with  { ... company: 'nike' ..}
.as-console-wrapper { max-height: 100% !important; top: 0; }
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40
  • I suggest using [`some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some) instead of [`find`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find) for this scenario. `some` returns `true` or `false` if a match is found. `find` returns the found element. – 3limin4t0r Sep 15 '20 at 14:34
  • @3limin4t0r correct, `array.some()` method is much smarter to use, thanks for that hint! (why didn't I think about it!) – Mister Jojo Sep 15 '20 at 15:36
1

You need to use Array.filter and then loop through your items for a match

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const data = [
    {
        id:0,
        company: "nike"
            items:[
                  name: "caret",
                  price:100
            ]
    },
    {
        id:1,
        company: "adidas"
            items:[
                name: "mobile phone",
                price: 300
            ]
    },
    ]

const filteredCompanies = data.filter((company)=>{
    company.items.forEach((item)=>{
        if(item.name === "nike") return true
    })
})
  • Thanks for your comment. Yet, I want to return the same array without the targeted object filtered. – Saif Sep 15 '20 at 12:40
  • @Saif what you mean by same array? – brk Sep 15 '20 at 12:43
  • do you mean the array of `data` or the array of `items`? – James Rushford Sep 15 '20 at 12:47
  • I mean the array of data. @JamesRushford – Saif Sep 15 '20 at 12:47
  • `return filteredCompanies` ? or else, if you want it all intact, less the items that do not match, do `return data.map((company)=> { company.items = company.items.filter((item)=> item.name === "carat") return company }` – James Rushford Sep 15 '20 at 12:53
  • @JamesRushford why company is involved?! I want to filter upon the name inside the items array! – Saif Sep 15 '20 at 13:01
  • The way Array.map works, is that is that is runs a function using each item in the array as the input for the function and replaces each value with what is returned. So, when we say `company` what we mean is each item in the array, i thought company might be the best name for these items. In this case, we say we want to examine each item in the array that is `data`, we want to adjust the property called `items` to be a filtered list of `items` where we only want items that have a property called `name` that has a value of `"carat"`. then, we want to return the changed `company` to `data` – James Rushford Sep 15 '20 at 13:12
  • One-liner : `data.filter( company => !!company.items.find( item => item.name==="nike"))` – Jeremy Thille Sep 15 '20 at 13:38
  • 1
    This answer does not work using `return true` inside an `forEach` callback will only return from the `forEach` callback, not from the `filter` callback. – 3limin4t0r Sep 15 '20 at 14:31