2012-09-26 130 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