0

I'm trying to filter an array, like for example the I want it to return all the color, sizes and etc., I know you can it filter it by doing something like this :

const products = [
  {
    name: "Product A",
    attributes: [
      {
        color: "Yellow",
        size: "Small",
        price: 100,
        quantity: 30,
      },
      {
        color: "Yellow",
        size: "Medium",
        price: 150,
        quantity: 20,
      },
      {
        color: "Yellow",
        size: "Large",
        price: 200,
        quantity: 10,
      },
      {
        color: "Red",
        size: "Small",
        price: 100,
        quantity: 15,
      },
      {
        color: "Red",
        size: "Medium",
        price: 150,
        quantity: 10,
      },
      {
        color: "Red",
        size: "Large",
        price: 200,
        quantity: 5,
      },
      {
        color: "Blue",
        size: "Small",
        price: 100,
        quantity: 15,
      },
      {
        color: "Blue",
        size: "Medium",
        price: 150,
        quantity: 10,
      },
      {
        color: "Blue",
        size: "Large",
        price: 200,
        quantity: 5,
      },
    ],
  },
];

const result = data.map(({ attributes }) =>
    attributes.filter(({ color }) => color === "Red")
  );. 

console.log(result)

But what if there are like 100 attribute color and sizes, how to maybe like separate them via there color sample if yellow array it will return all the yellow data like this

[
      {
        color: "Yellow",
        size: "Small",
        price: 100,
        quantity: 30,
      },
      {
        color: "Yellow",
        size: "Medium",
        price: 150,
        quantity: 20,
      },
      {
        color: "Yellow",
        size: "Large",
        price: 200,
        quantity: 10,
      },
]

for sizes it will return for example small it will return all the small data like this:

[{
    color: "Yellow",
    size: "Small",
    price: 100,
    quantity: 30,
  },
  {
    color: "Red",
    size: "Small",
    price: 100,
    quantity: 15,
  },
  {
    color: "Blue",
    size: "Small",
    price: 100,
    quantity: 15,
  }]

If my question isn't that clear, comment down below so I could explain further. Thanks for your help

Mohammad Khan
  • 313
  • 4
  • 20
  • So https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter – epascarello Jul 29 '21 at 16:31
  • hi @epascarello thanks for your comment, is there any kind of example you could give for my problem? – Mohammad Khan Jul 29 '21 at 16:32
  • 1
    It's not very clear what you're really asking here. If you're asking how to filter, see [these answers](https://stackoverflow.com/questions/13594788/javascript-filter-array-of-objects). If you're asking how to access an object property dynamically using a variable (e.g., `"size"` vs. `"color"`), see [these answers](https://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable). (Those play together, too.) – T.J. Crowder Jul 29 '21 at 16:32
  • 1
    `products.attributes.filter(item => item.color === "Blue")` – epascarello Jul 29 '21 at 16:35
  • Hi @T.J.Crowder I got an idea thanks for commenting – Mohammad Khan Jul 29 '21 at 16:41

3 Answers3

1

This doesn't really match the format of the question but it is an effective answer.

const array = [
  {
    color: "red",
    size: "small"
  },
  {
    color: "yellow",
    size: "small"
  },
  {
    color: "red",
    size: "large"
  }
];

function sortArrayByItemProperties(array, ...properties) {
  const map = {};
  for(let i = 0; i < properties.length; i++) {
    const property = properties[i];
    map[property] = {};
    for(let ii = 0; ii < array.length; ii++) {
      const object = array[ii];
      if(!map[property][object[property]]) map[property][object[property]] = [];
      map[property][object[property]].push(object);
    }
  }
  return map;
}

console.log(JSON.stringify(sortArrayByItemProperties(array, "color", "size")));
Other Me
  • 498
  • 2
  • 7
  • Hi thanks for answering just what I needed, sorry for asking but can you do it with es6 functions like map or something? – Mohammad Khan Jul 29 '21 at 16:41
  • so does `of` not work? I personally don't use `map` myself to be honest, I can change it to ordinary loops though would that work? – Other Me Jul 29 '21 at 16:46
  • no it works thankfully not really familiar for loops, just gonna have to study I guess to manipulate the data – Mohammad Khan Jul 29 '21 at 16:47
1

Simple by using Array.filter. Hope you are expecting this output format.

var attributes = [{color:"Yellow",size:"Small",price:100,quantity:30},{color:"Yellow",size:"Medium",price:150,quantity:20},{color:"Yellow",size:"Large",price:200,quantity:10},{color:"Red",size:"Small",price:100,quantity:15},{color:"Red",size:"Medium",price:150,quantity:10},{color:"Red",size:"Large",price:200,quantity:5},{color:"Blue",size:"Small",price:100,quantity:15},{color:"Blue",size:"Medium",price:150,quantity:10},{color:"Blue",size:"Large",price:200,quantity:5}];

function filterBy(attr, val)
{
    return attributes.filter(item => item[attr] == val);
}

console.log(filterBy("color", "Yellow"));
console.log(filterBy("size", "Large"));
console.log(filterBy("price", 200));
Vignesh Raja
  • 7,927
  • 1
  • 33
  • 42
0

As an addition i think getting attribute values dynamically with following code block would be good though.

const colors = []
const sizes = []
const prices = []
const quantities = []

for (product of products) {
  for (attribute of product.attributes) {
    if (colors.indexOf(attribute.color) == -1) {
      colors.push(attribute.color)
    }
    if (sizes.indexOf(attribute.size) == -1) {
      sizes.push(attribute.size)
    }
    if (prices.indexOf(attribute.price) == -1) {
      prices.push(attribute.price)
    }
    if (quantities.indexOf(attribute.quantity) == -1) {
      quantities.push(attribute.quantity)
    }
  }
}

And then you can get values by array.filter

for (product of products) {
  const result = product.attributes.filter(function(attributes) {
    return attributes.color == "Red"
  })
}
EmreSr
  • 11
  • 4