-1

I have a variable result that contains around 1M entries, which looks like this:

result = [
  {
    'name': 'x',
    'other fields': '...',
  },
  {
    'name': 'y',
    'other fields': '...',
  },
  .. and so on ..
]

I want to create another array that only contains a list of names but in object format:

nameArray = [
  {name: 'x'},
  {name: 'y'},
  .. and so on ..
]

I am currently using the following loop, but it is extremely slow for 1M entries

let nameArray = []
result.forEach(item => {
  let name = {name : item.name}
  nameArray.push(name)
});

What would be the fastest way to achieve this? I also tried lodash maps but still a little slow. But I would prefer not using lodash since it adds one more dependency.

pewpewlasers
  • 3,025
  • 4
  • 31
  • 58
  • Your original array already contains your desired output. Why not simply ignoring the other properties? – Gerardo Furtado Nov 28 '22 at 12:13
  • @GerardoFurtado Because the original contains way too many keys. I need to keep this variable in memory so need to reduce its size. – pewpewlasers Nov 28 '22 at 12:15
  • u could maybe somehow split the array in n arrays and use different promises to push the values to the new array, so they run async in different threads. – ericmp Nov 28 '22 at 12:18
  • I would guess the cost is because of the push() call - use a map instead e.g. ```let nameArray = result.map(item => ({ name: item.name }))``` – Woody Nov 28 '22 at 12:20
  • Why do you have a million records in a variable? Can you explain your use case? – adiga Nov 28 '22 at 12:29

2 Answers2

1

Here is a snippet with a sample array having 1M elements:

var arr=[]
for (let i=0;i<1000000; i++) arr.push({name:"id"+i, a:"abc", b:"def"+i});
console.log("input data created", arr.length);

// method 1: Array.map
// ====================
let time=new Date().getTime();
const res=arr.map(({name})=>({name}));
time=new Date().getTime() - time;
console.log(`Method 1 (.map) in ${time}ms , res:`, JSON.stringify(res.slice(0,10)));

// method 2: while loop
// =====================
const names = [];
arr=arr.reverse()
let i = arr.length;
time = new Date().getTime();
while (i--) names.push({name: arr[i].name});
time = new Date().getTime() - time;
console.log(`Method 2 (while) in ${time}ms , res:`, JSON.stringify(names.slice(0,10)));

The comparison shows that both methods have very similar executing times ( I got values between 38ms and 48ms on my old HP Elitebool 840 G4 ).

Carsten Massmann
  • 26,510
  • 2
  • 22
  • 43
0

Using for .. of should be more performant than forEach

const namesResults = []
for (const { name } of result) {
  namesResults.push(name)
}

Here a SO question with some explanation behind this

If you really need the most performant loop for this, I would try all the different methods and benchmark them. Other good candidates should be .reduce and .map

Aramil Rey
  • 3,387
  • 1
  • 19
  • 30