0

I am trying to build an array with a custom string index to get the item faster. The console.log of arr2 is showing the 3 items wierdly but I can't enum them, it is only showing the first item.

I m using react so I can't build an object instead

    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
    }) 

The question is how to enum all the items in arr2 because the forEach only output the first

4
  • Can you explain what is the question? Commented Jan 14, 2022 at 18:43
  • What results do you expect? You can edit and write a bit more :) Like: What I'm expected the final result is like this, like that. Commented Jan 14, 2022 at 18:43
  • Turned your code into a snippet. Use it in future when posting code Commented Jan 14, 2022 at 18:48
  • As you can see, the output you claim is different from what actually logs. Can you explain better? Commented Jan 14, 2022 at 18:49

4 Answers 4

1

You are trying to set the key of objects within an array, instead of creating an object with keys,

i.e instead of

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

you would want:

let obj2 = {}
arr.forEach((item) => {
   obj2[item.barcode] = item
})
Sign up to request clarification or add additional context in comments.

2 Comments

Im also wandering why he said "I m using react so I can't build an object instead"
that looks correct but when I tried to build an object with defineProperty, I have an error passing this in props and when you build the object like an array, I have no error. So yes, I am still wandering too
0

use map instead as below

  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 }*/

Comments

0

Create for this a object. To loop over the object you can loop with 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);
}

Comments

0

You are currently setting additional properties on an array object. Which is not the intent of an array. An array is expected to be a numbered list, so is probably not the best fit.

I suggest a Map instance, which is intended to hold key/value pairs. Map instances can also be easily iterated with a for...of loop or the forEach() method.

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);
});


You could also use an empty object instead of a Map. They can be iterated with for...in or you can first convert it back to an array with Object.entries() and then iterate it like you otherwise would.

However your standard object does have some hidden (non-iterable) properties like toString, valueOf, constructor and other standard properties (unless created with Object.create(null)).

If you intent to use an object solely for key/value data holding it's probably best to use Object.create(null) to initialize it. Or just use a Map, which is specifically designed to hold key/value pairs.

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")
  // ...
}

I'd recommend you to check out the Objects vs. Maps documentation if you are interested in the differences.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.