0

I was trying to create a prototype on Array to return the array with each element uppercased. I was trying to think of an efficient way of handling it but couldn't think of anything that didn't involved iterating through it and placing them in a temp array, which I then return.

Array.prototype.toUpperCase = function() {
      let array = this;
       let temp = [];
      array.forEach(x => {
         temp.push(x.toUpperCase());
      })

     return temp;
}

Is there a more efficient way, without iterating over the array?

timmyLtus
  • 274
  • 1
  • 12
  • 4
    Not really, since you need to access every element to create the new array, you have no choice but to iterate over the original array – CertainPerformance Sep 30 '20 at 22:57
  • 2
    `function(){ return this.map(it => it.toUpperCase()); }`, you don't need to make the array yourself. – Taplar Sep 30 '20 at 23:01
  • 1
    In either case, have a look at [How to define method in javascript on `Array.prototype` and `Object.prototype` so that it doesn't appear in for in loop](https://stackoverflow.com/q/13296340/1048572) – Bergi Oct 01 '20 at 00:16

2 Answers2

1

efficient? no. you still have to access each element in the array to operate on it, no matter how you look at it... but...

more readable and or less code. yes.

using map you use only a single line.

Array.prototype.toUpperCase = function() {
    return this.map(x =>x.toUpperCase())
}

the time complexity is still BigO(n). since you have visit each index to operate the function.

in addition, you might want to test first that each element is able to use .toUpperCase() in the first place...

an alternative to using a return to make a new array is mutating the array, something that's frown upon now adays becuase bugs tend to be harder to track, and state gets to be a mess.

Array.prototype.toUpperCase = function() {
    this = this.map(x =>x.toUpperCase())
}
//EDIT: turns out this is just wrong for a couple of reasons... don't do this. see comment section.
altruios
  • 986
  • 1
  • 10
  • 29
  • 1
    `this = this.map(x =>x.toUpperCase())` wouldn't actually change the current array. – VLAZ Sep 30 '20 at 23:08
  • oh, it wouldn't? is 'this' different than the array that called toUpperCase()? prototypes are not my strong point in js. why does it not modify this? and what would modify the array that calls the function? – altruios Sep 30 '20 at 23:11
  • 2
    Two reasons here 1. Assigning to a variable doesn't *change* it outside. So `x = {a : 1}; fn = (y) => y = {b : 2}; fn(x); console.log(x)` will still log `{a: 1}`. There aren't pointers in JS nor are you modifying the reference itself with the assignment. `fn` will just re-use the `y` binding and assign a new value to it but wouldn't modify the `x` that's passed in. 2. Probably more relevant but still - you cannot assign to `this`. It's an error. – VLAZ Sep 30 '20 at 23:15
  • interesting and informative discussion, thank you both – timmyLtus Oct 01 '20 at 00:25
0

Unless you are storing information about which of the array elements are already upper case as they are added (e.g. in a separate object/array) you are going to have to iterate through the entire array via a for loop or forEach/map call.

Think of it this way, how can you guarantee that all elements in an array are uppercase without checking each element either on insert or when you return them.