1

I have an array

fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}

it contains simple and nested objects as items

i can reference f1 using bracket notation like fruit[0]["dry"]["f1"] but i have a string variable that has the value var str="dry.f1"

value of "str" changes on runtime it could be "sweet" or "dry.f1" or "sour"

how do i reference the array item using "str" if the value of str is either "sweet" or "sour" fruit[str] works fine

we can get the value of f1 using fruit[0].dry.f1 but i need to access it using the variable str

charlietfl
  • 170,828
  • 13
  • 121
  • 150
user1613338
  • 153
  • 1
  • 2
  • 9
  • 1
    Really simple way is use lodash library which has `get()` method that will take your string as input and return nested values by parsing internally – charlietfl Nov 13 '17 at 01:21
  • I'd also like to point out that this is usually not the right structure of JSON for such data. It should rather be something like `fruit={sweet:'apple',dry:['raisin', 'almond'],sour:'strawberry'}` – sid-m Nov 13 '17 at 01:26
  • @sid-m what is wrong with the structure? – charlietfl Nov 13 '17 at 01:40
  • Note that what you've shown doesn't include an array, though your `fruit[0]["dry"]["f1"]` implies the object shown is in an array that isn't shown. @sid-m - that's not JSON. – nnnnnn Nov 13 '17 at 01:41

4 Answers4

4

You can use split and reduce:

var fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'};

var str1 = "dry.f1";
var str2 = "sweet";

var example1 = str1.split('.').reduce((a, b) => a[b], fruit);
var example2 = str2.split('.').reduce((a, b) => a[b], fruit);

console.log(example1);
console.log(example2);

This will split your string on each dot into an array, and then reduce the fruit array by iterating through the values from the string, applying them to the fruit array, to get the value you are looking for.

Chava Geldzahler
  • 3,605
  • 1
  • 18
  • 32
  • Thanks Chava, Ur solution worked. Will it affect the performance if the array has many rows and this is being used inside for loop to iterate through each row? – user1613338 Nov 13 '17 at 02:55
0

Given array:

fruit={sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}

And your string:

var str="dry.f1"

To lookup value fruit.dry.f1 you essentially need to write a parser for "dry.f1"

There are plenty of libraries out there that solve this. I give an example below.

AngularJS

Examples of such parsers exist e.g. angular 1.x's $parse: https://docs.angularjs.org/api/ng/service/$parse

var getter = $parse('dry.f1');
var setter = getter.assign;
var context = {sweet:'apple',dry:{f1:'raisin',f2:'almond'},sour:'strawberry'}

expect(getter(context)).toEqual('raisin');

Lodash

Lodash has a get method: https://lodash.com/docs/4.17.4#get

basarat
  • 261,912
  • 58
  • 460
  • 511
0

You could make a conditional, if statement that checks if the string has a dot using str.indexOf('.') and do either

fruit[str]

Or

fruit[str1][str2]
Andrija Ćeranić
  • 1,633
  • 11
  • 14
0

In order to access a value in an object given it's path, we must write a function that searches for that value path inside of the object.

Using split and reduce, we use split to break the path into an array of values that were dot-separated in the path (i.e. "dry.f1" becomes ["dry", "f1"]). We then use reduce to iterate over these values in the array, getting deeper into the object in each iteration until we have our value:

function findValueByPath(obj, path) {

    return path.split(".").reduce(function(objSoFar, currPath) {

        return objSoFar[currPath];

    }, obj);
}

For example, findValueByPath( {a: { b: 5 } } , "a.b") returns 5.

Click here to read more about reduce. Click here to read more about split.

As a side note, this problem is commonly implemented by libraries such as Lodash, which has the function get that does exactly this (click here for get documentation in Lodash).

Christian Santos
  • 5,386
  • 1
  • 18
  • 24