连接字符串中的额外字符阻止与对象键匹配

Javascript: Extra character in concatenated string preventing match with object key

本文关键字:对象 字符 字符串 连接      更新时间:2023-09-26

我正在尝试使用对象键访问另一个对象中的对象。我正在连接一组<select>元素的值,以构建一个与键匹配的字符串。不幸的是,这行不通。下面是代码:

    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];
    } 

在尝试了很多东西之后,我使用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];
    } 

我连接的字符串在连接时都有一个额外的字符,字符码为0。无法弄清楚为什么它在那里,或者如何使用regEx或str.replace()摆脱它。最终得到了一个丑陋但功能强大的解决方案,我只是测试对象键,看看它们是否包含<select>元素的值:

    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];
            }  
        });
    } 

一定有更好的办法,对吧?这到底是怎么回事?

编辑:rowValueGroups可能看起来像这样:

{
  "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应该是"45_to_54_yearsMale"或类似的。

这是调查数据。我从nicolaskruchten/数据透视表自定义渲染器的输出中提取rowValueGroups数据。(特别是从pivotData.tree对象,如果你好奇的话)。我不希望改变数据透视表核心来改变这些键的格式,所以我只是想从一个选择元素中连接几个值来使其工作。

下面是上面测试的部分控制台输出:

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

第一行是对valueKeyString进行的测试,第二行是对rowValueGroups中的一个键进行的测试。注意,初始字符串看起来是一样的(对于valueKeyString的字符串,Firefox控制台实际上在"years"answers"Male"之间输出一个没有找到字符的小方块),但是charCodeAt()在连接点出现了那个奇怪的0字符。

字符串中有null字符。这个正则表达式将删除它们:

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

参考:在JavaScript中从字符串中删除空字符

如果您确定了字符代码,您可以尝试使用完全相同的代码来替换它:

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

或者假设字符串已经直接从jquery的$(this).val()'0结尾,你可以尝试另一种方法:

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

上面的代码片段检查从$(this).val()获得的每个新字符串的最后一个字符是否以空结束(只是为了确保),并删除substring()的最后一个字符。

既然你使用的是jQuery,你可以试试trim():

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