【问题标题】:Array and Object Manipulation JS数组和对象操作 JS
【发布时间】:2021-04-09 20:43:56
【问题描述】:

所以我在练习一些 JS,这就是我在数组中遇到的嵌套对象。
如何访问 symbol === "S" color === "red"ID === 0 的数量值

const productUpdated = 
  [ { id    : 0
    , price : 4999
    , title : "Updated MEN'S JEANS"
    , name  : "SLIM Updated LEVI’S"
    , varient: 
      [ { color: 'red', size: 
          [ { symbol: 'S',  quant: 10 } 
          , { symbol: 'L',  quant:  0 } 
          , { symbol: 'XL', quant:  1 } 
          ] 
        } 
      , { color: 'green', size: 
          [ { symbol: 'S',  quant: 5 } 
          , { symbol: 'L',  quant: 1 } 
          , { symbol: 'XL', quant: 6 } 
          ] 
    } ] } 
  , { id    : 2
    , price : 4999
    , title : "Updated MEN'S JEANS"
    , name  : "SLIM Updated LEVI’S"
    , varient: 
      [ { color: 'red', size: 
          [ { symbol: 'S',  quant: 10 } 
          , { symbol: 'L',  quant:  0 } 
          , { symbol: 'XL', quant:  1 } 
          ] 
        } 
      , { color: 'green', size: 
          [ { symbol: 'S',  quant: 5 } 
          , { symbol: 'L',  quant: 1 } 
          , { symbol: 'XL', quant: 6 } 
  ] } ] } ] 

我想更新或使用最深嵌套变量的值。
如果可能的话,我想使用地图或过滤器来做到这一点,但我不是专家。

【问题讨论】:

  • 在 map/filter 之后您希望拥有的最终结构是什么?数组 ?如果是,应该有哪个结构?
  • console.log( productUpdated[0].varient[0].color ) --> red

标签: javascript arrays object nested


【解决方案1】:

您可以使用查找和过滤数组方法访问数量字段。 如果修改嵌套对象和数组中的元素,您可以在数组和对象中使用直接变异,但在嵌套对象/数组中变异是危险的。

相反,您可以将不可变修饰符(如 redux)与 immer 一起使用

我用 getQuantity 的工作示例做了一个 sn-p,带有可变和不可变修改的 setQuantity

const productUpdated = [
    {
        id: 0,
        price: 4999,
        title: "Updated MEN'S JEANS",
        name: 'SLIM Updated LEVI’S',
        varient: [
            {
                color: 'red',
                size: [
                    { symbol: 'S', quant: 10 },
                    { symbol: 'L', quant: 0 },
                    { symbol: 'XL', quant: 1 },
                ],
            },
            {
                color: 'green',
                size: [
                    { symbol: 'S', quant: 5 },
                    { symbol: 'L', quant: 1 },
                    { symbol: 'XL', quant: 6 },
                ],
            },
        ],
    },
    {
        id: 2,
        price: 4999,
        title: "Updated MEN'S JEANS",
        name: 'SLIM Updated LEVI’S',
        varient: [
            {
                color: 'red',
                size: [
                    { symbol: 'S', quant: 10 },
                    { symbol: 'L', quant: 0 },
                    { symbol: 'XL', quant: 1 },
                ],
            },
            {
                color: 'green',
                size: [
                    { symbol: 'S', quant: 5 },
                    { symbol: 'L', quant: 1 },
                    { symbol: 'XL', quant: 6 },
                ],
            },
        ],
    },
];

function getQuantity(id, color, size) {
    return productUpdated
        .find((product) => product.id === id)
        .varient.find((variant) => variant.color === color)
        .size.find((siz) => siz.symbol === size)?.quant;
}

function setQuantity(id, color, size, newQuantity) {
    console.log('Dangerous !!');
    const selectedSize = productUpdated
        .find((product) => product.id === id)
        .varient.find((variant) => variant.color === color)
        .size.find((siz) => siz.symbol === size);
    if (selectedSize) {
        selectedSize.quant = newQuantity;
    }
}

function immutableSetQuantity(id, color, size, newQuantity) {
    const selectedProduct = productUpdated.find((product) => product.id === id);
    const selectedVariant = selectedProduct.varient.find((variant) => variant.color === color);
    const selectedSize = selectedVariant.size.find((siz) => siz.symbol == size);
    return [
        {
            ...selectedProduct,
            varient: [
                {
                    ...selectedVariant,
                    size: [
                        { ...selectedSize, quant: newQuantity },
                        ...selectedVariant.size.filter((siz) => siz.symbol !== size),
                    ],
                },
                ...selectedProduct.varient.filter((variant) => variant.color !== color),
            ],
        },
        ...productUpdated.filter((product) => product.id !== id),
    ];
}

const quantity = getQuantity(0, 'red', 'S');

console.log({ quantity });

setQuantity(0, 'red', 'S', 11);

console.log(JSON.stringify(productUpdated, null, 2));

const products = immutableSetQuantity(0, 'red', 'S', 12);

console.log(JSON.stringify(products, null, 2));

【讨论】:

    【解决方案2】:

    我将从 get 用例开始:

    const PRODUCT_ID = 0;
    const COLOR = 'red';
    const SIZE = 'S';
    
    const product = productUpdated.find(({ id }) => id === PRODUCT_ID);
    
    const colorVarients = product?.varient.filter(({ color }) => color === COLOR) || [];
    
    const filteredSize = colorVarients[0].size.filter(({ symbol }) => symbol === SIZE);
    
    console.log('quantity', filteredSize[0].quant);
    

    在更新部分,我使用了不可变结构,起初可能很复杂,所以我同意@sadok 所说的:

    const NEW_QUANT = 55;
    
    const updatedProducts = productUpdated.reduce((acc, product) => {
      if (product.id === PRODUCT_ID) {
        const colorVarient = product.varient.filter(({ color }) => color === COLOR);
        if (colorVarient.length > 0) {
          const isSizeExisting = colorVarient.some((varient) =>
            varient.size.some((size) => size.symbol === SIZE)
          );
          if (isSizeExisting) {
            return [
              ...acc,
              {
                ...product,
                varient: product.varient.map((varient) => ({
                  ...varient,
                  size: varient.size.map((size) => {
                    if (size.symbol === SIZE && varient.color === COLOR) {
                      return { ...size, quant: NEW_QUANT };
                    }
                    return size;
                  }),
                })),
              },
            ];
          }
    
          return [...acc, product];
        }
      }
      return [...acc, product];
    }, []);
    
    console.log('updatedProducts', JSON.stringify(updatedProducts, null, 4));
    

    const productUpdated = [
      {
        id: 0,
        price: 4999,
        title: "Updated MEN'S JEANS",
        name: 'SLIM Updated LEVI’S',
        varient: [
          {
            color: 'red',
            size: [
              {
                symbol: 'S',
                quant: 10,
              },
              {
                symbol: 'L',
                quant: 0,
              },
              {
                symbol: 'XL',
                quant: 1,
              },
            ],
          },
          {
            color: 'green',
            size: [
              {
                symbol: 'S',
                quant: 5,
              },
              {
                symbol: 'L',
                quant: 1,
              },
              {
                symbol: 'XL',
                quant: 6,
              },
            ],
          },
        ],
      },
      {
        id: 2,
        price: 4999,
        title: "Updated MEN'S JEANS",
        name: 'SLIM Updated LEVI’S',
        varient: [
          {
            color: 'red',
            size: [
              {
                symbol: 'S',
                quant: 10,
              },
              {
                symbol: 'L',
                quant: 0,
              },
              {
                symbol: 'XL',
                quant: 1,
              },
            ],
          },
          {
            color: 'green',
            size: [
              {
                symbol: 'S',
                quant: 5,
              },
              {
                symbol: 'L',
                quant: 1,
              },
              {
                symbol: 'XL',
                quant: 6,
              },
            ],
          },
        ],
      },
    ];
    
    const PRODUCT_ID = 0;
    const COLOR = 'red';
    const SIZE = 'S';
    
    const product = productUpdated.find(({ id }) => id === PRODUCT_ID);
    
    const colorVarients = product?.varient.filter(({ color }) => color === COLOR) || [];
    
    const filteredSize = colorVarients[0].size.filter(({ symbol }) => symbol === SIZE);
    
    console.log('quantity', filteredSize[0].quant);
    
    const NEW_QUANT = 55;
    
    const updatedProducts = productUpdated.reduce((acc, product) => {
      if (product.id === PRODUCT_ID) {
        const colorVarient = product.varient.filter(({ color }) => color === COLOR);
        if (colorVarient.length > 0) {
          const isSizeExisting = colorVarient.some((varient) =>
            varient.size.some((size) => size.symbol === SIZE && varient.color === COLOR)
          );
          if (isSizeExisting) {
            return [
              ...acc,
              {
                ...product,
                varient: product.varient.map((varient) => ({
                  ...varient,
                  size: varient.size.map((size) => {
                    if (size.symbol === SIZE && varient.color === COLOR) {
                      return { ...size, quant: NEW_QUANT };
                    }
                    return size;
                  }),
                })),
              },
            ];
          }
    
          return [...acc, product];
        }
      }
      return [...acc, product];
    }, []);
    
    console.log('updatedProducts', JSON.stringify(updatedProducts, null, 4));

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-07
      • 1970-01-01
      相关资源
      最近更新 更多