Home > Net >  filter an object and get rid of an attribute using react JS
filter an object and get rid of an attribute using react JS

Time:07-26

    Objects:[
      {id:'a',
       owner: 'b',
       products:[{productId:'a1',name:'b1'},{productId:'a2',name:'b2'}]
       date: '2-2'},
    
      {id:'e',
       owner: 'f',
       products:[{productId:'a3',name:'b3'},{productId:'a4',name:'b4'}]
       date: '1-1'}

      {id:'g',
       owner: 'y',
       products:[{productId:'a4',name:'b3'},{productId:'a7',name:'b9'}]
       date: '1-3'}
     ]

Result:

[{id:'e',
 owner: 'f',
 products:[{productId:'a3',name:'b3'}]
 date: '1-1'}

 {id:'g',
   owner: 'y',
   products:[{productId:'a4',name:'b3'}]
   date: '1-3'}]

In above example, how do I get the second object by the value of name:'b3'? and get rid of this part {productId:'a4',name:'b4'} The name is an attribute of products array and products is an attribute of objects array. I'll appreciate if someone can help me out.

CodePudding user response:

You could practically achieve the result you desire in 2 steps, first by using Array.find to find the object. And then by using Array.filter to filter out all other products. Like this:

const objects = [
  {
    id: 'a',
    owner: 'b',
    products: [
      { productId: 'a1', name: 'b1' },
      { productId: 'a2', name: 'b2' },
    ],
    date: '2-2',
  },
  {
    id: 'e',
    owner: 'f',
    products: [
      { productId: 'a3', name: 'b3' },
      { productId: 'a4', name: 'b4' },
    ],
    date: '1-1',
  },
];

const searchVal = 'b3';

let result = objects.find((obj) => obj.products.some((p) => p.name === searchVal));

if (result) {
  result = {
    ...result,
    products: result.products.filter((r) => r.name === searchVal)
  }
}

console.log(result);

If you're planning using this approach on multiple different places in your code, then you could also create a function to handle it for you:

const objects = [
  {
    id: 'a',
    owner: 'b',
    products: [
      { productId: 'a1', name: 'b1' },
      { productId: 'a2', name: 'b2' },
    ],
    date: '2-2',
  },
  {
    id: 'e',
    owner: 'f',
    products: [
      { productId: 'a3', name: 'b3' },
      { productId: 'a4', name: 'b4' },
    ],
    date: '1-1',
  },
];

const getObjectWithFilteredProducts = (objArr, searchVal) => {
  let result = objects.find((obj) => obj.products.some((p) => p.name === searchVal));

  if (result) {
    result = {
      ...result,
      products: result.products.filter((r) => r.name === searchVal),
    };
  }

  return result;
};

console.log(getObjectWithFilteredProducts(objects, 'b3'));

EDIT

If you want an array as your result, you could do it like this:

const objects = [
  {
    id: 'a',
    owner: 'b',
    products: [
      { productId: 'a1', name: 'b1' },
      { productId: 'a2', name: 'b2' },
    ],
    date: '2-2',
  },
  {
    id: 'e',
    owner: 'f',
    products: [
      { productId: 'a3', name: 'b3' },
      { productId: 'a4', name: 'b4' },
    ],
    date: '1-1',
  },
];

const searchVal = 'b3';

const result = objects.reduce((acc, obj) => {
  if (obj.products.some((p) => p.name === searchVal)) {
    return [
      ...acc,
      {
        ...obj,
        products: obj.products.filter((p) => p.name === searchVal),
      },
    ];
  }

  return acc;
}, []);

console.log(result);

CodePudding user response:

I guess you can do something like this. Your existing filter will find the top level object that contains a product with the correct name. If that object is found, you can then filter the array of products, matching on searchValue

const tempObjects = Objects.filter((obj) => hasProductsByName(obj.products))

let products = []

temp.forEach(
  (obj) =>
    (products = products.concat(
      obj.products.filter((product) => product.name === searchValue)
    ))
)

products should now contain all products matching the searchValue

  • Related