0

A javascript data object (JSON notation) has been created with the following content:

"[
   {"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},
   {"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}
]"

In a next step the index of an ordinal value has to be found in this object. The function should find the index of the value 'Blue' in the range 'Color'.

So the function should have the meta scripting form

f("Color")("Blue")=1

What is the most elegant form to create such a function in the context of D3 and javascript?

6
  • How do you define "elegant"? Commented Jun 21, 2015 at 22:38
  • As in direct access, readable code, no looping involved. I'd like to solve this with dictionary like access. Commented Jun 21, 2015 at 22:42
  • "I'd like to solve this with dictionary like access" Then you should simply change the data structure. If you are performing such lookups multiple times, it makes sense to restructure the data. You can do this dynamically once when you received the data. Commented Jun 21, 2015 at 22:44
  • Could you elaborate this suggestion in an example? Commented Jun 21, 2015 at 22:46
  • 1
    Convert your data structure to {Shape: ['Random', 'Line', ...]} and you can do data['Shape'].indexOf('Line'). Or go even one step further and convert to {Shape: {Random: 0, Line: 1, ..}} and do data['Shape']['Line']. What the best solution is depends on the actual use case. Commented Jun 21, 2015 at 22:47

2 Answers 2

2

Depending on your use case, it might make sense to convert the data structure to a different structure more suitable for direct access. E.g. you could convert your structure to

var data = {
    Shape: ['Random', 'Line', ...], 
    // ...
};

and access it with

data['Shape'].indexOf('Line') // or data.Shape.indexOf('Line')

Or go even one step further and convert to

var data = {
    Shape: {
      Random: 0,
      Line: 1, 
      // ...
    },
    // ...
};

and access it with

data['Shape']['Line'] // or data.Shape.Line

What the best solution is depends on the actual use case.


Converting the structure dynamically is pretty straight forward. Here is an example to convert it to the first suggestion:

var newData = {};
data.forEach(function(item) {
    newData[item.range] = 
        item.values.map(function(value) { return value.val; });
});

This would also reduce redundancy (e.g. idx seems to correspond with the element index).

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

Comments

0

Would this work for you ?

var dataJson = '[ \
   {"range":"Shape","values":[{"idx":0,"val":"Random"},{"idx":1,"val":"Line"},{"idx":2,"val":"Square"},{"idx":3,"val":"Circle"},{"idx":4,"val":"Oval"},{"idx":5,"val":"Egg"}]},\
   {"range":"Color","values":[{"idx":0,"val":"Red"},{"idx":1,"val":"Blue"},{"idx":2,"val":"Yellow"},{"idx":3,"val":"Green"},{"idx":4,"val":"Cyan"}]}\
]';

var data = JSON.parse(dataJson);

for (each in data){
   if ( (data[each].range) === 'Color'){
      for (eachVal in data[each].values){
         if (data[each].values[eachVal].val === 'Blue'){
            alert(data[each].values[eachVal].idx);
         }
      }
   } ;
}

And here is the JSFiddle for you too.

4 Comments

Thanks, this is working indeed. But is this the most elegant solution? I would guess there should be a more direct access to the value, without the double loop.
@MartijnvanderJagt: Not really, you have two nested collections, you have to iterate one way or the other. However, you could use Array#find or Array#findIndex instead of the inner loop if your environment supports it: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
I have a question, if I may ask here. Array#find or Array#findIndex should iterate through object properties under the hood too, shouldn't it ? But I agree these make code more readable and eliminates possible bugs.
@Alp: Yes. That's what I meant to imply by "one way or the other".

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.