1

Been going at this for a while, figured I'd post it here for some help.

items = { '417': { a: 23, slot_position: 13 },
  '419': { a: 28, slot_position: 2 },
  '420': { a: 29, slot_position: 12 },
  '421': { a: 29, slot_position: 3 },
  '424': { a: 31, slot_position: 17 },
  '425': { a: 32, slot_position: 7 },
  '428': { a: 35, slot_position: 0 },
  '429': { a: 36, slot_position: 0 },
  '431': { a: 42, slot_position: 0 },
  '432': { a: 40, slot_position: 0 },
  '433': { a: 43, slot_position: 11 },
  '434': { a: 44, slot_position: 0 },
  '435': { a: 45, slot_position: 0 },
  '436': { a: 47, slot_position: 0 },
  '437': { a: 48, slot_position: 15 },
  '438': { a: 48, slot_position: 1 },
  '439': { a: 48, slot_position: 0 },
  '440': { a: 48, slot_position: 14 },
  '441': { a: 43, slot_position: 0 },
  '442': { a: 44, slot_position: 0 },
  '443': { a: 43, slot_position: 8 },
  '444': { a: 37, slot_position: 0 },
  '445': { a: 37, slot_position: 0 },
  '446': { a: 37, slot_position: 0 },
  '447': { a: 37, slot_position: 16 },
  '451': { a: 50, slot_position: 5 },
  '452': { a: 49, slot_position: 6 },
  '453': { a: 39, slot_position: 20 },
  '454': { a: 38, slot_position: 4 },
  '455': { a: 19, slot_position: 19 },
  '456': { a: 49, slot_position: 9 },
  '457': { a: 51, slot_position: 0 } };

inventory_slots = 30;
used_slots = [];
for(a in items){
    if(items[a].slot_position > 0){
       used_slots.push(items[a].slot_position);
    }
}


console.log(used_slots);

See on jsfiddle: http://jsfiddle.net/sf71L5jq/6/

So, a user has 30 available inventory slots. And the above console logs this array:

[13, 2, 12, 3, 17, 7, 11, 15, 1, 14, 8, 16, 5, 6, 20, 4, 19, 9]

How would I go about finding that first open number (slot)? In this case, it should be 10. But how to accomplish this dynamically?

Edit: @Tim Lewis's idea is here: http://jsfiddle.net/sf71L5jq/8/ But it doesn't catch the correct number. (NOTE: Not saying his idea is wrong, it's probably my code).

for(i=1; i < inventory_slots; i++){
    if(used_slots[i] != i){
        first_open = used_slots[i];  // Why is first_open assigned '2'?
        break;
    }
}
NiCk Newman
  • 1,716
  • 7
  • 23
  • 48
  • I dont get what you want... – tymeJV May 29 '15 at 18:28
  • Not sure how to explain it, but after reading my question I thought of this: If there is an array like `[1,3,4,5,6,8,9]` how would you go about finding what the `FIRST` missing number is dynamically? (2) – NiCk Newman May 29 '15 at 18:29
  • You should show a bit more on what you've tried, but in a nutshell, you have a few options. Option 1: sort values from 1 - 30, loop through the sorted array and exit at the first value that doesn't equal your increment. Option 2: Use an `in-array` like function starting from 1, exit when you don't find the first value. Etc etc. – Tim Lewis May 29 '15 at 18:29
  • @TimLewis I tried that already but it doens't work. Let me post it in my question. – NiCk Newman May 29 '15 at 18:30
  • 1
    That should be the first thing you do, so I don't have to post comments like that :P – Tim Lewis May 29 '15 at 18:31
  • 1
    I don't understand what an "open slot" is. Consider adding a paragraph or a step by step of what this program is supposed to do. As of now this is too vague – samrap May 29 '15 at 18:33
  • Nevermind your edit helped – samrap May 29 '15 at 18:34
  • [Here](http://stackoverflow.com/a/2113827/3199927) is a highly voted answer on how to do it in java. Shouldn't take much to convert that idea into your answer. – Tom May 29 '15 at 18:35
  • I don't see any sorting in that array; which would be an issue if trying to find the **first** slot that doesn't equal your incrementing value. – Tim Lewis May 29 '15 at 18:35

3 Answers3

2

Assuming used slot values always start at 1, sort the array, then loop through it and compare the current increment with the current value. For example, after sorting your example array above, it would look like this:

[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 19, 20]

As you loop through, starting at 1, compare the increment variable with the current value:

if (used_slots[i] != (i+1)) {
    // You have found the open slot
}

Full code would look like:

(See: How to sort an array of integers correctly for sorting integers)

function sortNumber(a,b) {
    return a - b;
}
used_slots.sort(sortNumber);

for (i = 0; i < used_slots.length; i++) {
    if (used_slots[i] != (i+1)) {
        // You have found the open slot
    }
}
Community
  • 1
  • 1
samrap
  • 5,595
  • 5
  • 31
  • 56
2

First of all, the values need to be sorted in numeric order:

used_slots.sort(sortNumber);

function sortNumber(a, b){
    return a - b;
}

Next, loop through using a counter and find the first index that doesn't match your counter:

for(i = 0; i < inventory_slots; i++){
    if(used_slots[i] != i+1){
        first_open = i+1;  
        break;
    }
}
console.log(first_open); // 10

In this case, the first open slot is 10. Also note, index starts at 0, not 1, but slot numbers start at 1, which explains the comparison if(used_slots[i] != i+1) and assignment first_open = i+1;

Tim Lewis
  • 27,813
  • 13
  • 73
  • 102
  • Awww.. So I need to just check it against another loop but it needs to be re-ordered for the comparison numbers to be legit / match up. Got it. – NiCk Newman May 29 '15 at 18:46
  • 1
    Yeah, or else you'd be looking at the value of index `0` which should be `1 (0 + 1)`, but in the unsorted list, it could be anything :P – Tim Lewis May 29 '15 at 18:47
1

Try something like

for(var i=1; used_slots.indexOf(i) > 0; ++i);
i; // 10

But note indexOf will be slow for huge arrays. Better use searches in a hash table.

var hashTable = Object.create(null);
for(p in items) if(items.hasOwnProperty(p))
  hashTable[items[p].slot_position] = true;
for(var i=1; hashTable[i]; ++i);
i; // 10
Oriol
  • 274,082
  • 63
  • 437
  • 513