When you write array.push(gr.room) you are pushing a GlideElement onto an array. A GlideElement is an object. So what you are actually doing is pushing the memory address of that object onto your array.
Each time you go around the while loop the GlideElement gr.room will contain different content, but it is the same object with the same memory address. It would be very inefficient if ServiceNow were to allocate new memory for all the elements in a record every time a new record was read. When the loop ends, your array will contain a bunch of references to the same object, and that object will contain the last value that you read.
The method getValue returns a String, so when you write array.push(gr.getValue("room")) you are pushing a string value onto your array.
Here are several solutions that will work. What these solutions have in common is that they push a string value (and not a reusable object) onto the array.
array.push(gr.getValue("room"));
array.push(gr.room + "");
array.push(gr.room.toString());
array.push(String(gr.room));
array.push(gr.room.toString())?gr = gr.next()after push statement will help?grrecycles objects to save on garbage collection, andgr.next()just returns the same object each time but mutates it so its string is different. I would hope that this behaviour is documented somewhere, because OP shouldn't be punished for writing perfectly idiomatic-looking code.