3

I'm trying to access an object within another object using an object key. I'm concatenating the values of a group of <select> elements to build a string that matches the key. Unfortunately this never works. Here's the code below:

    var valueKeyString = "";
    $(".keySelector").each(function(){
        valueKeyString += $(this).val();
    });
    if (geoAttrs[selectedGeoAttr].rowCol == "row") {
        mapData = rowValueGroups[valueKeyString];
    } else if (geoAttrs[selectedGeoAttr].rowCol == "col") {
        mapData = colValueGroups[valueKeyString];
    } 

After trying a good number of things I tested the strings character by character using charCodeAt():

    var test1 = valueKeyString;
    for (var i = 0, len = valueKeyString.length; i < len; i++) {
      test1 += valueKeyString.charCodeAt(i)+" ";
    }
    if (geoAttrs[selectedGeoAttr].rowCol == "row") {
        Object.keys(colValueGroups).forEach(function(group) {
            var test2 = group;
            for (var i = 0, len = group.length; i < len; i++) {
              test2 += group.charCodeAt(i)+" ";
            }
            console.log(test1);
            console.log(test2)                
        })

        mapData = colValueGroups[valueKeyString];
    } 

My concatenated strings all had an extra character with a charCode of 0 at the point of concatenation. Couldn't figure out why it was there or how to get rid of it using a regEx or str.replace(). Ended up with an ugly but functional solution where I just test the object keys to see if they contain the values from the <select> elements:

    var valueKeys = [];
    $(".keySelector").each(function(){
        valueKeys.push($(this).val());
    });
    if (geoAttrs[selectedGeoAttr].rowCol == "row") {
        Object.keys(colValueGroups).forEach(function(group) {
            var groupHasAllKeys = true;
                valueKeys.forEach(function(key) {
                    if (group.indexOf(key) == -1 ) {
                        groupHasAllKeys = false;
                    }
                });
            if(groupHasAllKeys) {
                mapData = colValueGroups[group];
            }  
        });
    } else if (geoAttrs[selectedGeoAttr].rowCol == "col") {
        Object.keys(rowValueGroups).forEach(function(group) {
            var groupHasAllKeys = true;
                valueKeys.forEach(function(key) {
                    if (group.indexOf(key) == -1 ) {
                        groupHasAllKeys = false;
                    }
                });
            if(groupHasAllKeys) {
                mapData = rowValueGroups[group];
            }  
        });
    } 

There's got to be a better way, right? What the hell is going on here?

EDIT: rowValueGroups might look something like this:

{
  "35_to_44_yearsMale": {
    "4654387684": {
      "value": 215
    },
    "4654387685": {
      "value": 175
    },
    "4654387686": {
      "value": 687
    },
    "4654387687": {
      "value": 172
    }
  },
  "45_to_54_yearsMale": {
    "4654387684": {
      "value": 516
    },
    "4654387685": {
      "value": 223
    },
    "4654387686": {
      "value": 54
    },
    "4654387687": {
      "value": 164
    }
  }
}

valueKeyString should be "45_to_54_yearsMale" or the like.

This is survey data. I'm extracting the rowValueGroups data from the output of a nicolaskruchten/pivottable custom renderer. (Specifically from the pivotData.tree object if you're curious). I'm not looking to alter the pivottable core to change how those keys are formatted, so I just figured I'd concatenate a couple of values from a select element to make it work.

Here's part of the console output from the tests above:

35_to_44_yearsMale51 53 95 116 111 95 52 52 95 121 101 97 114 115 0 77 97 108 101
35_to_44_yearsMale51 53 95 116 111 95 52 52 95 121 101 97 114 115 77 97 108 101

First line is the test done on valueKeyString and the second on one of the keys from rowValueGroups. Note that the initial string looks identical, (the Firefox console actually outputs a little character-not-found square in between "years" and "Male" for the valueKeyString one) but the charCodeAt() turns up that weird 0 character at the point of concatenation.

8
  • 1
    An example of values would be helpful, for valueKeyString and rowValueGroups. Would make it easier to get an idea of what you're trying to achieve Commented Sep 26, 2015 at 22:57
  • Added details in an Edit. Commented Sep 26, 2015 at 23:42
  • What if you just cleaned the string after your each? Like valueKeyString = valueKeyString.replace(/[^a-z0-9_-]+/gi,'') Commented Sep 27, 2015 at 9:10
  • Gave it a try. It doesn't clean out that weird character. It seems like regular expressions and the like don't actually recognize it as a character so they can't get rid of it. Nevertheless it seems enough to keep the strings from matching. Commented Sep 27, 2015 at 15:16
  • Can you give us a reproducible demo on jsfiddle? I am particularly interested in the html for the keySelector elements. Commented Oct 26, 2015 at 2:03

3 Answers 3

1
+50

You have null characters in your string. This regex will remove them:

valueKeyString = valueKeyString.replace( /\0/g, '' )

Reference: Removing null characters from a string in JavaScript

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

Comments

0

If you identify the char code you can try to replace it using exactly its code:

var valueKeyString = "";
$(".keySelector").each(function(){
    valueKeyString += $(this).val();
});
valueKeyString = valueKeyString.replace(new RegExp(String.fromCharCode(0),"g"),'');

Or presuming the string already comes \0-terminated directly from the jquery $(this).val() you can try another approach:

var valueKeyString = "";
$(".keySelector").each(function(){
    s = $(this).val();
    if ( s.charCodeAt(s.length - 1) == 0 )
        s = s.substring(0, s.length - 1);
    valueKeyString += s;
});

The above snippet check if the last char of each freshly obtained string from $(this).val() is null-terminated (just to be sure) and remove the last char with substring().

1 Comment

Neither solution will effectively remove the weird 0 character. It's as if it's not a real character, just something else there that returns a char code of 0. I haven't been able to find any effective way of removing it.
-1

Since you are using jQuery you can try trim():

var valueKeyString = "";
$(".keySelector").each(function(){
    valueKeyString += $(this).val().trim();
});

Comments

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.