2

I have that J Stsrutcure:

var rooms={};
rooms["room1"] = 10;
rooms["room2"] = 25;
rooms["room3"] = 15;
rooms["room4"] = 1;
rooms["room5"] = 10;
rooms["room6"] = 181;
rooms["somrthing"] = value;

I am trying to write a function that will retrieve the FIRST N elements

ex:

function getElements(limit) {
..
}

if limit = 3 will return an Object like:

Object 
{room1: 10, room2: 25, room3: 15}

(the first 3 elements : I don' need ordering !)

yarek
  • 8,962
  • 25
  • 93
  • 180
  • 2
    Objects in JS have no inherent ordering. How are you defining the order? Lexicographically by key? Why not use an array instead? – Matt Ball May 08 '15 at 20:42
  • 1
    `Object.keys(rooms).slice(0,limit).reduce(function(a,b){a[b]=rooms[b];return a;},{})` – dandavis May 08 '15 at 20:42
  • Use an array (of objects) and the `Array.prototype.slice` method. – undefined May 08 '15 at 20:43
  • 2
    @dandavis There's no guarantee that `Object.keys()` will return the keys in the same order that he originally assigned them. – Barmar May 08 '15 at 20:43
  • @Barmar: what are the odds of it being different? – dandavis May 08 '15 at 20:43
  • I don't need sorting or ordering ! – yarek May 08 '15 at 20:48
  • Define "TOP elements"! – undefined May 08 '15 at 20:51
  • Yes: it was stupid from my part to use "TOP" keyword. – yarek May 08 '15 at 20:53
  • @yarek If there's no ordering, what does it mean to be "first 3"? – Barmar May 08 '15 at 20:55
  • @dandavis See http://stackoverflow.com/questions/26245482/sorting-algorithm-in-javascript/26246038#comment41172461_26246038 – guest271314 May 08 '15 at 20:55
  • Check out this thread to understand why we can't really give you an answer: http://stackoverflow.com/questions/5525795/does-javascript-guarantee-object-property-order – talemyn May 08 '15 at 20:55
  • 1
    Why are you all answering the question in the comments space? – RudePeopleStepOff May 08 '15 at 20:59
  • to be more specific than "no", just know that properties of an object that pass `/^[a-zA-Z_]/.test(key)` will maintain order in all known JS implementations, even if the spec doesn't holistically nail down the issue until ES6, which basically codifies what V8 has been doing for years (since the backfire from the release that didn't behave like that, where numericals are sorted and letters are kept in insertion order). in short, given the code shown, my previous 1-line code comment can be tested anywhere and pass as-is. – dandavis May 08 '15 at 21:00

4 Answers4

2
function getTopElements(limit) {
    var newRooms = {};
    var i = 0;
    for(r in rooms) {
        if(i < limit) {
            newRooms[r] = rooms[r];
            i++;
        }
        else
            return newRooms;
    }
    return newRooms;
}

jsfiddle DEMO

Samurai
  • 3,588
  • 5
  • 23
  • 36
0

There is no concept of order in an associative array. You're using the wrong data structure. If you want to keep track of order, then you need to use a data structure that inherently keeps track of order, like a regular array.

Most likely, you just want to replace your associative array with an array in the following way: Instead of using the string "room1" as a key, use an array like so:

var rooms = [] 
rooms[1] = 10 //but maybe you want to start at 0 instead of 1
// because the array WILL have a 0 element

etc. Then it's easy to get the first N items in the array in whatever fashion you please. To return whatever value is in rooms[1], you just call rooms[1].

It's also possible you want to keep track of both the name of the room and some other number associated to it, as in your current associative array, as well as the order in which the data was stored. In that situation, perhaps what you want is some kind of room object. For example:

room1 = {
    room_number : 1, 
    other_number : 10, //I don't know what this number means in your code
} 

Then you can fill an array rooms with objects of this kind any way you like. Once the object Room1 above is created, you can push it to an array like this:

rooms.push(room1);  

In this situation, maybe the order is supposed to mean something other than the room number. That's for your to judge.

  • If you want this to be a reasonable answer, you should show how to do it right in the code. Otherwise, it's no more than the comments that were already posted by several people. – Barmar May 08 '15 at 20:56
  • 1
    Your comments were answers posted in the wrong place. Answers should be posted as answers. – RudePeopleStepOff May 08 '15 at 20:57
0

As pointed out in all of the comments, there is now way to guarantee the "first three" properties of an object in JS, because it has no inherent order in an Object. As such, if you were to use a for (i in obj) {} loop and put a counter in it to track the number of loops that you'd been through, so that you could stop at 3 (for example), different browsers could return you three different properties.


So . . . try storing your data like this . . . it is similar to what you are using and will allow you to support numerating your data more easily:

var rooms = [
    {room: "room1",
     number: 10},
    {room: "room2",
     number: "25"},
    {room: "room3",
     number: "15"},
    {room: "room4",
     number: "1"},
    {room: "room5",
     number: "10"},
    {room: "room6",
     number: "181"}
];

rooms[0].room would get you room1, rooms[0].room would equal 10 . . . loop through as many as you want after that, to get the next ones in line.


Alernately, if the "roomn" values are just being used to enumerate the values, do you need them at all? You could use a simple array:

var rooms = [10, 25, 15, 1, 10, 181];

With that, rooms[0] would equal 10, rooms[1] would equal 25, etc.


In either case, looping through (or slicing off) the first three entries would be easily supported.

talemyn
  • 7,110
  • 4
  • 25
  • 45
0

Try utilizing a "map" of last "digits" in property names of rooms object ; filter , add selected properties from rooms to new res object at for in loop

var value = 123;

var rooms = {};
rooms["room1"] = 10;
rooms["room2"] = 25;
rooms["room3"] = 15;
rooms["room4"] = 1;
rooms["room5"] = 10;
rooms["room6"] = 181;
rooms["somrthing"] = value;

var res = {};

var map = "123".split("");

for (var prop in rooms) {
  // if property name ends with "digit"; e.g., "1", "2", "3"
  if (prop.match(/\d$/) !== null 
         // if property name is within `map`
      && map.indexOf(prop.match(/\d/)[0]) !== -1) {
        // set `prop` at `res` with `prop` value
        res[prop] = rooms[prop];
  }
};

console.log(res);
guest271314
  • 1
  • 10
  • 82
  • 156