1

Using a previously answered SO question as a reference, I created a function that populates a dropdown list in my HTML doc from an existing javascript array.

Here's the HTML:

<fieldset>
    <legend>Choose action</legend>
        <p>Choose your action and click next</p><br />
            <select id="trigger"></select>
</fieldset>

Here's the Javascript:

var guns =
    [
        ["Smith and Wesson 500", "Revolver", "Full Frame", 50, "sada"], //model, type, frame, cal, trigger
        ["Glock 19", "Semi", "Compact", 9, "striker"],
        ["Smith and Wesson M and P Shield 9", "Semi", "Compact", 9, "striker"],
        ["Ruger Alaskan", "Revolver", "Full Frame", 44, "dao"],
        ["Ruger SR9", "Semi", "Compact", 9, "striker"],
        ["Desert Eagle", "Semi", "Full Frame", 50, "sada"],
        ["Smith and Wesson M and P Shield 40", "Semi", "Compact", 40, "striker"]
    ]   

var triggerDropdown = function(){
    var sel = document.getElementById('trigger');
    for (var i = 0; i < guns.length; i++) {
        var opt = document.createElement('option');
        opt.innerHTML = guns[i][4];
        opt.value = guns[i][4];
        sel.appendChild(opt);
        }
    };

My challenge:

Populate trigger without duplicates. Also, the solution must not require me to permanently change guns (I found a few other helpful SO posts, but most of them involve first removing duplicates from the array...in this case, I don't have the option).

Thank you!

1
  • 1
    You say you can't change guns, but you can change a copy of it: var gunsCopy = guns.slice(0) (just don't modify any of the inner arrays, or you'll be changing guns too). Remove the duplicates from the copy, and use that to populate the dropdown. Commented May 8, 2013 at 2:33

2 Answers 2

2

You can create a separate array with just the triggers:

var triggers = function(guns) {
  var unique = {};

  return guns.reduce(function(current, item) {
    if (!(item[4] in unique)) {
      current.push(item[4]);
      unique[item[4]] = 1;
    }
    return current;
  }, []);
}(guns);

Demo

Then iterate over triggers as per normal.

See also: Array.reduce()

Sign up to request clarification or add additional context in comments.

3 Comments

Short but quite inefficient, it's a lot better to use a lookup object and loop once.
@plalx Agreed and updated; looping over the guns array and immediately populating would be even better, but that answer has been given already :)
Way better now! The advantage of this one would be if the array has to be reused ;) However, I think it's a better practice to wrap a self-executing function in ().
1

When building the list, keep track locally of the keys you've already used:

var triggerDropdown = function(){

    var already = {};
    var sel = document.getElementById('trigger');
    for (var i = 0; i < guns.length; i++) 
    {
      var val = guns[i][4];

      if (! already[val]) 
      {
        var opt = document.createElement('option');
        opt.innerHTML = val;
        opt.value = val;
        sel.appendChild(opt);

        already[val] = true;
      }
    }
};

6 Comments

This worked very well. I was going down this path while trying to figure it out, but kept falling all over myself. Exactly what I was looking for. Thanks Paul!
@PaulRoub, Probably the best way, however you should have a look at JavaScript best practices dev.opera.com/articles/view/javascript-best-practices.
@plalx Bookmarked--can't wait to read, and find out all the crap I've been doing wrong :). For real, thank you for the reference!
There's Javascript best practices, and then there's "close enough to the original code to make the differences clear", which seemed more helpful in this case.
@PaulRoub, It doesn't hurt to learn more than a single thing ;) But yeah, it is probably easier to understand without too many changes.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.