【问题标题】:Build an array with string index用字符串索引构建一个数组
【发布时间】:2022-01-14 18:37:29
【问题描述】:

我正在尝试使用自定义字符串索引构建一个数组以更快地获取项目。 arr2 的 console.log 奇怪地显示了 3 个项目,但我无法枚举它们,它只显示第一个项目。

我正在使用 react,所以我无法构建一个对象

    let arr = [
       {
           "barcode": "27034FAZ019",
           "name": "Item 1",
           "price": 0.99,
           "stock": 10
       },
       {
           "barcode": "404E47HV1768",
           "name": "Item 2",
           "price": 2.99,
           "stock": 10
       },
       {
           "barcode": "325KS6130LG76",
           "name": "Item 3",
           "price": 5.99,
           "stock": 10
       }
    ]
      
    let arr2 = []
    arr.forEach((item) => {
       arr2[item.barcode] = item
    })
    
    console.log(arr2); //shows 3 items wierdly
    
    arr2.forEach((item) => {
       console.log(item); //shows only the first item
    }) 

问题是如何枚举arr2中的所有项目,因为forEach只输出第一个

【问题讨论】:

  • 你能解释一下是什么问题吗?
  • 您期待什么结果?可以编辑多写一点:) Like: 我期待的最终结果是这样的,那样的。
  • 把你的代码变成了一个sn-p。以后在发布代码时使用它
  • 如您所见,您声称的输出与实际记录的不同。你能解释清楚吗?

标签: javascript


【解决方案1】:

您正在尝试设置数组中对象的键,而不是使用键创建对象,

即代替

let arr2 = []
arr.forEach((item) => {
   arr2[item.barcode] = item
})

你会想要的:

let obj2 = {}
arr.forEach((item) => {
   obj2[item.barcode] = item
})

【讨论】:

  • 我也想知道为什么他说“我正在使用反应,所以我不能构建一个对象”
  • 这看起来是正确的,但是当我尝试使用 defineProperty 构建一个对象时,我在 props 中传递它时出错,当你像数组一样构建对象时,我没有错误。所以是的,我也在徘徊
【解决方案2】:

如下使用地图

  let arr = [
       {
           "barcode": "27034FAZ019",
           "name": "Item 1",
           "price": 0.99,
           "stock": 10
       },
       {
           "barcode": "404E47HV1768",
           "name": "Item 2",
           "price": 2.99,
           "stock": 10
       },
       {
           "barcode": "325KS6130LG76",
           "name": "Item 3",
           "price": 5.99,
           "stock": 10
       }
    ]
    
    let arr2 = new Map();
    arr.forEach(item => {
        arr2.set(item.barcode, item);
    })
    console.log(arr2);
    
    /*
     Map(3) {
  '27034FAZ019' => { barcode: '27034FAZ019', name: 'Item 1', price: 0.99, stock: 10 },
  '404E47HV1768' => { barcode: '404E47HV1768', name: 'Item 2', price: 2.99, stock: 10 },
  '325KS6130LG76' => { barcode: '325KS6130LG76', name: 'Item 3', price: 5.99, stock: 10 }
}
*/
    arr2.forEach(item => console.log(item));
    /*{ barcode: '27034FAZ019', name: 'Item 1', price: 0.99, stock: 10 }
{ barcode: '404E47HV1768', name: 'Item 2', price: 2.99, stock: 10 }
{ barcode: '325KS6130LG76', name: 'Item 3', price: 5.99, stock: 10 }*/

【讨论】:

    【解决方案3】:

    为此创建一个对象。要遍历对象,您可以使用for...in Loop 进行循环。

    arr = [
           {
               "barcode": "27034FAZ019",
               "name": "Item 1",
               "price": 0.99,
               "stock": 10
           },
           {
               "barcode": "404E47HV1768",
               "name": "Item 2",
               "price": 2.99,
               "stock": 10
           },
           {
               "barcode": "325KS6130LG76",
               "name": "Item 3",
               "price": 5.99,
               "stock": 10
           }
        ]
      
    obj = {}
    arr.forEach((item) => {  
      obj[item.barcode] = item;
    })
    
    
    console.log('arr2',obj);
    
    for (key in obj) {
      console.log('item',obj[key], key);
    }

    【讨论】:

      【解决方案4】:

      您当前正在为数组对象设置其他属性。这不是数组的意图。数组应该是一个编号列表,因此可能不是最合适的。

      我建议使用Map 实例,该实例旨在保存键/值对。 Map 实例也可以通过for...of 循环或forEach() 方法轻松迭代。

      const arr = [
         {
             "barcode": "27034FAZ019",
             "name": "Item 1",
             "price": 0.99,
             "stock": 10
         },
         {
             "barcode": "404E47HV1768",
             "name": "Item 2",
             "price": 2.99,
             "stock": 10
         },
         {
             "barcode": "325KS6130LG76",
             "name": "Item 3",
             "price": 5.99,
             "stock": 10
         }
      ];
      
      const itemsByBarcode = new Map(arr.map(item => [item.barcode, item]));
      
      // access a single value by barcode
      console.log(itemsByBarcode.get("325KS6130LG76"));
      
      // iterate through the Map instance with for...of loop
      for (const [barcode, item] of itemsByBarcode) {
        console.log("for...of", barcode, item);
      }
      
      // iterate through the Map instance with forEach()
      itemsByBarcode.forEach((item, barcode) => {
        console.log("forEach()", barcode, item);
      });

      您也可以使用空对象代替Map。它们可以使用for...in 进行迭代,或者您可以先使用Object.entries() 将其转换回数组,然后像其他方式一样对其进行迭代。

      但是,您的标准对象确实具有一些隐藏(不可迭代)属性,例如 toStringvalueOfconstructor 和其他标准属性(除非使用 Object.create(null) 创建)。

      如果您打算仅将对象用于保存键/值数据,最好使用Object.create(null) 对其进行初始化。或者只使用 Map,它专门用于保存键/值对。

      const arr = [
         {
             "barcode": "27034FAZ019",
             "name": "Item 1",
             "price": 0.99,
             "stock": 10
         },
         {
             "barcode": "404E47HV1768",
             "name": "Item 2",
             "price": 2.99,
             "stock": 10
         },
         {
             "barcode": "325KS6130LG76",
             "name": "Item 3",
             "price": 5.99,
             "stock": 10
         }
      ];
      
      const itemsByBarcode = Object.create(null);
      for (const item of arr) {
        itemsByBarcode[item.barcode] = item;
      }
      
      // access a single value by barcode
      console.log(itemsByBarcode["325KS6130LG76"]);
      
      // iterate through the Map instance with for...of loop
      for (const barcode in itemsByBarcode) {
        console.log("for...in", barcode, itemsByBarcode[barcode]);
      }
      
      Object.entries(barcode).forEach(([barcode, item]) => {
        console.log("Object.enties() + forEach()", barcode, item);
      });
      // although the default properties are skipped during iteration they can
      // still for a problem if you want to check the presence.
      const input = "constructor";
      
      // check if a barcode is present in an object
      if (input in itemsByBarcode) {
        // will run if `itemsByBarcode` was not created using Object.create(null)
        // ...
      }
      
      // vs
      
      // check if a barcode is present in a Map
      if (itemsByBarcode.has(input)) {
        // never runs (unless an actual barcode value is "constructor")
        // ...
      }
      

      如果您对差异感兴趣,我建议您查看Objects vs. Maps documentation

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-03-15
        • 2013-05-21
        • 1970-01-01
        • 1970-01-01
        • 2012-05-04
        • 1970-01-01
        • 2012-07-20
        相关资源
        最近更新 更多