DEV Community

Cover image for JS Array Manipulation Quirks

JS Array Manipulation Quirks

Jen Chan on December 07, 2019

In my previous post I mentioned Iā€™d been practicing problem-solving by handwriting answers. It's taking much longer than on an IDE or cargo-program...
Collapse
 
shiftyp profile image
Ryan Kahn (he/him) • Edited

Good points! You could iterate through a string directly though with a for loop, accessing the character at each index!

function forEachChar(str, cb) {
   for (let i = 0; i < str.length; i++) {
      cb(str.charAt(i))
   }
}
Collapse
 
willsmart profile image
willsmart • Edited

As a rule I see charAt/charCodeAt/length for strings as useful optimisations in well-curated performance code and anti-patterns in typical code.

They are great if you know what's in the string (i.e. you made it or "sanitised" it to take all the interesting bits out), but can get you in trouble for arbitrary user input where at some stage some fool is going to try out some fancier unicode.

spreadem = s => {
  for (let i=0; i<s.length; i++) console.log(`Char at index ${i}: '${s.charAt(i)}'`); 
  console.log(`Spread graphemes: '${[...s].join("', '")}'`);
}

charAt works nicely in the usual case:

> spreadem("01234")
< Char at index 0: '0'
< Char at index 1: '1'
< Char at index 2: '2'
< Char at index 3: '3'
< Char at index 4: '4'
< Spread graphemes: '0', '1', '2', '3', '4'

But get's funky when multi-char graphemes exist:

> spreadem("šŸ˜šŸ™šŸššŸ›šŸœ")
< Char at index 0: 'ļæ½'
< Char at index 1: 'ļæ½'
< Char at index 2: 'ļæ½'
< Char at index 3: 'ļæ½'
< Char at index 4: 'ļæ½'
< Char at index 5: 'ļæ½'
< Char at index 6: 'ļæ½'
< Char at index 7: 'ļæ½'
< Char at index 8: 'ļæ½'
< Char at index 9: 'ļæ½'
< Spread graphemes: 'šŸ˜', 'šŸ™', 'šŸš', 'šŸ›', 'šŸœ'

(see speakingjs.com/es5/ch24.html for a bit of background)

Collapse
 
shiftyp profile image
Ryan Kahn (he/him)

This is a really good point! Multi-character glyphs do mess with string iteration whether you split, spread, or loop. Trying to remember my solution to this the last time I encountered it in practice. I may have used a library to convert the strings to multi character arrays...

Collapse
 
jenc profile image
Jen Chan

Omg I have not thought of this either. Multi-char graphemes really mess with my head

Collapse
 
jenc profile image
Jen Chan

Wow yesss! I didn't think to!

Collapse
 
link2twenty profile image
Andrew Bone

const newArr = arr.slice()

Is my favourite way to clone an array

Collapse
 
jenc profile image
Jen Chan

woah woah woah! Does it clone past 1 level deep?

Collapse
 
link2twenty profile image
Andrew Bone
Collapse
 
karataev profile image
Eugene Karataev

forEach doesn't mutate an array. Mutation happens only if you explicitly mutate array items in iteration function.

Collapse
 
link2twenty profile image
Andrew Bone • Edited

I guess if you're using forEach like map you could say it mutates

arr.forEach(a => a = {id: a})

// VS

const newArr = arr.map(a => {id: a})

// VS

const newArr = [];
arr.forEach(a => newArr.push({id: a}))
Collapse
 
karataev profile image
Eugene Karataev

Well, actually if we execute your examples, we can notice that forEach doesn't mutate the original array.
forEach

Thread Thread
 
jenc profile image
Jen Chan • Edited

Thanks for pointing that out. This seems like a gray area. I don't know how I got under the impression that forEach mutates the original array items, maybe it was this post I looked up as I was writing the post. It's not entirely clear to me what forEach actually returns if I ran it on an array its own.

I have around the web read general opinions that forEach iterates straight through arrays without breaking, and skips empty values, so that if one wanted to include a condition it would be easier to go with a for-loop. I don't have enough experience with forEach to tell, tbh

Thread Thread
 
belvederef profile image
Francesco Belvedere

To address your point "what forEach actually returns", the answer is "nothing". forEach does not return a value, it is a void function.

Thread Thread
 
jenc profile image
Jen Chan

Thank you! That makes a lot of sense.