简体   繁体   中英

How can I update the state based on a deeply nested array?

I am having difficulty updating an array of products based on stock. This is the array:

const Data = [ gender: [{ male: true, female: false }], stock: [ { size: 3, stock: 100 }, { size: 3.5, stock: 10 }, { size: 4, stock: 0 }, { size: 4.5, stock: 330 }, { size: 5, stock: 5 }, { size: 5.5, stock: 555 }, { size: 6, stock: 6 }, { size: 6.5, stock: 63 }, { size: 7, stock: 0 }, { size: 7.5, stock: 100 }, { size: 8, stock: 33 }, { size: 8.5, stock: 333 }, { size: 9, stock: 222 }, { size: 9.5, stock: 99 }, { size: 10, stock: 99 }, { size: 10.5, stock: 77 }, { size: 11, stock: 55 } ] }, { gender: [{male: false, female: true }], stock: [ { size: 3, stock: 140 }, { size: 3.5, stock: 130 }, { size: 4, stock: 10 }, { size: 4.5, stock: 30 }, { size: 5, stock: 53 }, { size: 5.5, stock: 55 }, { size: 6, stock: 64 }, { size: 6.5, stock: 643 }, { size: 7, stock: 0 }, { size: 7.5, stock: 100 }, { size: 8, stock: 334 }, { size: 8.5, stock: 333 }, { size: 9, stock: 22 }, { size: 9.5, stock: 9 }, { size: 10, stock: 99 }, { size: 10.5, stock: 7 }, { size: 11, stock: 45 } ], } ]

I want to update the array based on the following criteria:

1) If the sizes that the client is choosing are not included in the array, I want to return only the product that includes the sizes being chosen. for this I am updating.

I have the following code to exemplify my goal:

var set3 = new Set([ 4, 5.5, 6, 6.5 ]);

const array = [];

for (const cat of set3) {

 array.push(cat)

}

I am pushing a set of numbers that the client chose to an array and I want to update the state only if the product includes these sizes (sizes: 4, 5.5, 6, 6.5).

2) I only want to return the product that includes the above criteria.

This is what I have tried so far:

var set3 = new Set([ 4, 5.5, 6, 6.5 ]);

const array = [];

for (const cat of set3) { array.push(cat) }

let mappedData = Data.map((product) => { return product.stock.map((item) => { if(item.stock === 0) { return item.size = undefined } else { return item.size } }) })

 mappedData.forEach((item, idx, array) => {check = array.every (r => item.indexOf(r) >= 0) if( check ) { console.log(item) } else { return item } })

When I console log the item it returns the item that includes what I am looking for but A) it does not update the product and B) when I console log it, it does not actually return the item I am looking for. I am sure this has to do with something I don't know about JavaScript.

You can filter the objects directly based on the selected sizes. The idea is that a product should be included if it has non-zero stock for all the selected sizes. The demo below includes data from your sandbox:

 const Data = [{"title":"Scotts","alternative_title":"Jeremy Scotts Pandabear","routeName":"Scotts","gender":[{"male":true,"female":true}],"brand":"Adidas","price":400,"stock":[{"size":3,"stock":100},{"size":3.5,"stock":10},{"size":4,"stock":0},{"size":4.5,"stock":330},{"size":5,"stock":5},{"size":5.5,"stock":555},{"size":6,"stock":6},{"size":6.5,"stock":63},{"size":7,"stock":0},{"size":7.5,"stock":100},{"size":8,"stock":33},{"size":8.5,"stock":333},{"size":9,"stock":222},{"size":9.5,"stock":99},{"size":10,"stock":99},{"size":10.5,"stock":77},{"size":11,"stock":55}],"description":"The Womens Air Jordan 1 Satin Black Toe” is a special construction of the original colorway of the Jordan 1 with satin paneling on the heel. Following the same blueprint of the Satin Shattered Backboard” colorway that was also a women's exclusive, this Satin Black Toe” edition features a black and white leather upper with red satin at the heel. The Air Jordan wings” logo on the ankle is presented in a metal medallion to complete the premium look. The Women's Air Jordan 1 Satin Black Toe” released on August 17, 2019 in limited quantities.","image":"https://drive.google.com/uc?id=1Uzaa15R2zn-YAozyyVi7RI5GAlhB0uCo"},{"title":"Boost 350 White","alternative_title":"Yeezy Boost 350 White","routeName":"yeezy","gender":[{"male":true,"female":false}],"brand":"Nike","price":200,"stock":[{"size":3,"stock":140},{"size":3.5,"stock":130},{"size":4,"stock":10},{"size":4.5,"stock":30},{"size":5,"stock":53},{"size":5.5,"stock":55},{"size":6,"stock":64},{"size":6.5,"stock":643},{"size":7,"stock":0},{"size":7.5,"stock":100},{"size":8,"stock":334},{"size":8.5,"stock":333},{"size":9,"stock":22},{"size":9.5,"stock":9},{"size":10,"stock":99},{"size":10.5,"stock":7},{"size":11,"stock":45}],"description":"The adidas Yeezy Boost 350 v2 Static released in December 2018, bringing a new look to Kanye Wests popular silhouette. The updated Yeezy 350 features a transparent mesh panel in place of the usual side stripe. The panel is woven into the Primeknit upper on each lateral side. The Yeezy 350 Static introduced an intricate new Primeknit pattern in white and grey hues. The clean appearance is solidified with a translucent white rubber midsole and outsole that wrap full-length Boost cushioning. The unique design of the adidas Yeezy Boost 350 v2 Static provided a refreshing update that will be in-demand for years to come.","image":"https://drive.google.com/uc?id=16Js6C1UyksZdVrPj_VdVKC16yYQcbMIp"},{"title":"Grey Yeezys","alternative_title":"Adidas Yeezy 500 Bone White","routeName":"yeezy-bone-whit","gender":[{"male":true,"female":false}],"brand":"Dolce & Gabbana","price":350,"stock":[{"size":3,"stock":140},{"size":3.5,"stock":10},{"size":4,"stock":1},{"size":4.5,"stock":340},{"size":5,"stock":53},{"size":5.5,"stock":55},{"size":6,"stock":654},{"size":6.5,"stock":43},{"size":7,"stock":90},{"size":7.5,"stock":70},{"size":8,"stock":34},{"size":8.5,"stock":33},{"size":9,"stock":2},{"size":9.5,"stock":94},{"size":10,"stock":9},{"size":10.5,"stock":0},{"size":11,"stock":0}]}] const set3 = new Set([11, 10.5]); const selectedSizes = [...set3]; const filteredProducts = Data.filter(product => selectedSizes.every(size => product.stock.some(s => s.stock > 0 && s.size === size))); console.log(filteredProducts);

@CodeManiac I am sorry, let me repost this so you can see what I did:

const mappedData = Data.map((product) => {

> return product.stock.map((item) => {  
if(item.stock === 0) {  
return
> item.size = false } 
 else {  return item.size } }) }).find((item) => { 
> const check = array.every(r => item.indexOf((r)) >= 0);  const state =
> [];  if( check ) { return item } else { return null } })

Also at this moment, this only returns the current size that does not include the numbers on the set. How would I return the actual product that matches the criteria?

I decided to include the code in a sandbox to get more help with this problem. I have not yet been able to solve this but I believe that I am really close:

https://codesandbox.io/s/stoic-kalam-6x3xj

As you can see in the sandbox, I am successfully getting back the sizes that are in stock based on the array however I am not returning the entire object. Would anyone be able to give me any advise on this?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM