2012-09-26 88 views
1

我试图抓取某个值。我是新来的JavaScript,我不明白为什么这不起作用。Javascript函数从字符串中拆分并返回一个值

如果我解析“kid_2”,我应该得到“kostas”。而不是“Kostas”我总是得到“02-23-2000”。所以我必须在循环中有一个逻辑问题,但我真的被卡住了。

function getold_val(fieldname,str){ 

    var chunks=str.split("||"); 
    var allchunks = chunks.length-1; 
    for(k=0;k<allchunks;k++){ 
     var n=str.indexOf(fieldname); 
     alert(chunks[k]); 
     if(n>0){ 
     var chunkd=chunks[k].split("::"); 
     alert(chunkd); 
     return chunkd[1]; 
     } 
    } 
} 
var test = getold_val('kid_2','date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||'); 

alert(test); 
+0

它应该是'allchunks = chunks.length 'not'allchunks = chunks.length-1' – slebetman

+1

另外,它应该是'if(n> = 0)',因为如果找到了键,它确实在位置0. – slebetman

+0

在这种情况下,它不应该返回任何东西。 – Barmar

回答

2

正则表达式可能会更具吸引力。这里有一个fiddle

function getValue(source, key){ 
    return (new RegExp("(^|\\|)" + key + "::([^$\\|]+)", "i").exec(source) || {})[2]; 
}  
getValue("date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||","kid_2"); 

但是,如果你想要的东西多一点参与,您可以分析字符串转换成一个字典,像这样(fiddle):

function splitToDictionary(val, fieldDelimiter, valueDelimiter){ 
    var dict = {}, 
    fields = val.split(fieldDelimiter), 
    kvp; 
    for (var i = 0; i < fields.length; i++) {   
     if (fields[i] !== "") { 
      kvp = fields[i].split(valueDelimiter);   
      dict[kvp[0]] = kvp[1]; 
     } 
    } 
    return dict;  
} 
var dict = splitToDictionary("date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||","||","::"); 
console.log(dict["date_1"]); 
console.log(dict["date_2"]); 
console.log(dict["kid_1"]); 
console.log(dict["kid_2"]);​ 
+0

一行代码。我的上帝,你是一个正则表达式怪胎:-) –

+0

我是Jscript中的新手,所以正如你所想象的那样,正则表达式太过先进。我真的非常感谢你的建议,完美的工作。 –

2

有两个错误。第一个错误是在indexOf电话:

var n = str.indexOf(fieldname); 

这将始终返回一个值大于或等于0,因为该领域的字符串中存在。你应该做的是:

var n = chunks[k].indexOf(fieldname); 

第二个错误是在你的if语句中。它应该是:

if(n >= 0) { 
    ... 
} 

if(n > -1) { 
    ... 
} 

你正在寻找的子很可能是在字符串的开头,在这种情况下,其指数为0。indexOf返回-1如果它无法找到你要找的东西。

话虽这么说,这里有一个更好的方式做你想要做什么:

function getold_val(fieldName, str) { 
    var keyValuePairs = str.split("||"); 
    var returnValue = null; 

    if(/||$/.match(str)) { 
     keyValuePairs = keyValuePairs.slice(0, keyValuePairs.length - 1); 
    } 

    var found = false; 
    var i = 0; 
    while(i < keyValuePairs.length && !found) { 
     var keyValuePair = keyValuePairs[i].split("::"); 

     var key = keyValuePair[0]; 
     var value = keyValuePair[1]; 

     if(fieldName === key) { 
      returnValue = value; 
      found = true; 
     } 

     i++; 
    } 

    return returnValue; 
} 
+0

Mihai,好点 - 我的错误;最后我没有看到“||”。 –

+0

@VivinPaliath虽然返回看起来正确。只有在密钥匹配的情况下才会执行。 – slebetman

+0

@slebetman没错 - 编辑。 –

2

这个工作,这是我fiddle

function getold_val(fieldname,str) { 
    var chunks = str.split('||'); 
    for(var i = 0; i < chunks.length-1; i++) { 
     if(chunks[i].indexOf(fieldname) >= 0) { 
      return(chunks[i].substring(fieldname.length+2)); 
     } 
    } 
} 
alert(getold_val('kid_2', 'date_1::02-23-2000||date_2::06-06-1990||kid_1::George||kid_2::Kostas||')); 

与您的代码的问题是(如@slebetman注意到还有)的事实,串索引可以是0,因为它在第一个字母开头正好。

代码与您的代码几乎相同,我只是没有使用第二个.split('::'),因为我觉得.substring(...)会更容易。

+0

我的上帝,你很快。请让我检查一下。 –

+0

其实,主要的问题是他在做'str.indexOf()'而不是'chunks [i] .indexOf()'。因此,在查看第一个块时,它会在不同的块中找到该域名。 – Barmar

+1

其实,使用indexOf也是一个bug。应该简单地将所有内容分解为一个数组(或对象数组),并简单地检查'key = fieldname'。这将在'kid_10'及以上的地方破解。 – slebetman