2

This is a pretty simple question, but I can't figure out what I'm doing wrong. Say I have this object:

features: {
    savings: {
        link: "test.html",
        img: "/_assets/img/related-content/sample.png"
    },
    security: {
        link: "test2.html",
        img: "/_assets/img/related-content/sample2.png"
    },
    speed: {
        link: "test3.html",
        img: "/_assets/img/related-content/sample3.png"
    }
}

Assume that this format is set and cannot be changed. I can easily select by doing something like features["savings"].link. But let's say I want to get a random item from this object. I would generate a random number, and then select the index using that. But features[randnum].link doesn't work. Why is this? How can I do this without modifying the object format?

Thanks!

Paul Erdos
  • 1,355
  • 2
  • 23
  • 47

3 Answers3

3

It's because you're dealing with an object, not an array, so you can't index into the object with just a number. You would have to do something like:

var randnum = getRandomNumber(1, 3); // get random num between 1 and 3
var randomLink = features["feature" + randnum].link;

Just for clarification, this notation:

features["feature1"].link;

is the same as

features.feature1.link;

If you don't have property names that you can easily generate, like "security" or "savings", you could use an array to help you out, assuming the properties are static.

var properties = [ "security", "savings" ];
var randomProperty = properties[Math.floor(Math.random() * properties.length)];
var randomLink = features[randomProperty].link;

If you don't know what you're properties are going to be, then you can collect them:

var properties = [];
for (var prop in features) {
    if (features.hasOwnProperty(prop)) {
        properties.push(prop);
    }
}
var randomProperty = properties[Math.floor(Math.random() * properties.length)];
var randomLink = features[randomProperty].link;
Einacio
  • 3,502
  • 1
  • 17
  • 21
Cᴏʀʏ
  • 105,112
  • 20
  • 162
  • 194
  • Let's say I had just category names (like security, savings, etc.) instead of feature1, feature2, etc. How would I do it then? – Paul Erdos Oct 20 '11 at 15:15
  • 1
    @ellenchristine: You could get all keys in an array and [choose an element randomly](http://stackoverflow.com/questions/4550505/javascript-getting-random-value-from-an-array). – Felix Kling Oct 20 '11 at 15:16
  • you could add a `for(x in features)` to populate the `properties` array – Einacio Oct 20 '11 at 15:22
0

js objects aren't numericaly indexed, you can't access it as an array using integers.

Einacio
  • 3,502
  • 1
  • 17
  • 21
  • I see. So I can only treat it as an associative array? – Paul Erdos Oct 20 '11 at 15:16
  • It's not an associate array though, it's an object. The syntax `myArray['myPropertyName']` is just a different way to access a property of an object. – Cᴏʀʏ Oct 20 '11 at 15:16
  • You can't say they aren't numerically indexed. I think in one sense or another all arrays are, if they aren't associative. Anyway.. Take a look at W3 for example, they show an indexed array there. And I know I have worked with objects/arrays where I've done something like myobj[0].myproperty. W3 ref: http://www.w3schools.com/js/js_obj_array.asp – chris Nov 18 '12 at 10:29
0

features[something] against your original json structure will make it look for features.something. However, you can actually make features an Array of json objects. this will give you your random access you want. However, it will be come a 'search' function to find feature3 unless you put some thought into creating the array.

for features[randomInteger].link, change to the structure below:

var features = [{
        name:"feature1",
        link: "test.html",
        img: "/_assets/img/related-content/sample.png"
    },
    {
        name:"feature2",
        link: "test2.html",
        img: "/_assets/img/related-content/sample2.png"
    },
    {
        name:"feature3",
        link: "test3.html",
        img: "/_assets/img/related-content/sample3.png"
    }]
DefyGravity
  • 5,681
  • 5
  • 32
  • 47