BaiClassmate Xiao
BaiClassmate Xiao

Reputation: 381

How does JS filter the contents of an array without confusion

I want to filter the content of 'phone'

I have the following code:

var testList = [{
content:[
    {id:1,uId:1,text:"apple", category: "phone"},
    {id:2,uId:2,text:"nick",category: "life"},
    {id:3,uId:3,text:"samsung",category: "phone"}],
user:[
 {id:1,name: "Joe"},
 {id:2,name: "red"},
 {id:3,name: "blue"}
  ]
}]

const newArrys = testList
  .filter((element) =>
    element.content.some((subElement) => subElement.category == "phone"))
  .map(element => {
    return Object.assign({}, element, {
      content: element.content.filter(subElement => subElement.category == "phone")
    });
  });
console.log(newArrys);

These are the returns:

[{
content:[
    {id:1,uId:1,text:"apple", category: "phone"},
    {id:3,uId:3,text:"samsung",category: "phone"}],
user:[
 {id:1,name: "Joe"},
 {id:2,name: "red"},
 {id:3,name: "blue"}
  ]
}]

I want the result:

[{
content:[
    {id:1,uId:1,text:"apple", category: "phone"},
    {id:3,uId:3,text:"samsung",category: "phone"}],
user:[
 {id:1,name: "Joe"},
 {id:3,name: "blue"}
  ]
}]

How should I filter 'user'? , and correspond to 'content'

Can you help me? thank you

Upvotes: 0

Views: 57

Answers (3)

Ricardo Ferreira
Ricardo Ferreira

Reputation: 616

Filter the content to find the category items and after filter the users in the list intens found.

var list = [
  {
    content:[
      {id:1,uId:1,text:"apple", category: "phone"},
      {id:2,uId:2,text:"nick",category: "life"},
      {id:3,uId:3,text:"samsung",category: "phone"}
    ],
    user:[
      {id:1,name: "Joe"},
      {id:2,name: "red"},
      {id:3,name: "blue"}
    ]
  }
];

const result = list.map(items => {
  const content = items.content.filter(c => c.category === 'phone');
  const users = items.user.filter(u => content.find(c => u.id === c.id));
  
  return {
    content: content,
    user: users,
  }
});
                         
 
console.log(result);

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386560

You could filter the indices first and then filter by wanted indices.

var testList = [{ content:[{ id: 1, uId: 1, text: "apple", category: "phone" }, { id: 2, uId: 2, text: "nick", category: "life" }, { id: 3, uId: 3, text: "samsung", category: "phone" }], user:[{ id: 1, name: "Joe" }, { id: 2, name: "red" }, { id: 3, name: "blue" }] }],
    result = testList.map(o => {
        var indices = [...o.content.keys()].filter(i => o.content[i].category === 'phone');
        return Object.assign({}, ...['content', 'user'].map(k => ({ [k]: o[k].filter((_, i) => indices.includes(i)) })));
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

Code Maniac
Code Maniac

Reputation: 37755

You can build a Set of id's that are having category as phone and then filter values based on the Set

var testList = [{content:[{id:1,uId:1,text:"apple", category: "phone"},{id:2,uId:2,text:"nick",category: "life"},{id:3,uId:3,text:"samsung",category: "phone"}],
user:[{id:1,name: "Joe"},{id:2,name: "red"},{id:3,name: "blue"}]}]

let final = testList.map(v => {
  let mapper = new Set(v.content.filter(({
    category
  }) => category === "phone").map(({
    id
  }) => id))
  return Object.fromEntries(Object.entries(v).map(([key, value]) => {
    value = value.filter(({
      id
    }) => mapper.has(id))
    return [key, value]
  }).filter(([_, value]) => value))
})

console.log(final)


if Object.fromEntries is not supported

var testList = [{content:[{id:1,uId:1,text:"apple", category: "phone"},{id:2,uId:2,text:"nick",category: "life"},{id:3,uId:3,text:"samsung",category: "phone"}],
user:[{id:1,name: "Joe"},{id:2,name: "red"},{id:3,name: "blue"}]}]

let final = testList.map(v => {
  let mapper = new Set(v.content.filter(({
    category
  }) => category === "phone").map(({
    id
  }) => id))
  return Object.entries(v).map(([key, value]) => {
    value = value.filter(({
      id
    }) => mapper.has(id))
    return [key, value]
  }).filter(([_, value]) => value).reduce((op,[k,v])=>{
    op[k] = v
    return op
  },{})
})

console.log(final)

Upvotes: 2

Related Questions