2017-06-05 52 views
4

注意: 在此時,我無法更好地將問題標題更改。如果有人能夠更好地交流,請繼續前進!在每個特定子字符串的出現處剪切JS字符串並追加到相同的數組

我有什麼:

var array = ["authentication.$.order", "difference.$.user.$.otherinformation", ... , ...] 

我需要什麼:

["authentication", "authentication.$", "authentication.$.order", 
"difference", "difference.$", "difference.$.user", "difference.$.user.$", 
"difference.$.user.$.otherinformation"] 

基本上,wherevever我看到.$.,我需要保留它,那麼的occourrence前追加一切.$.以及.$的所有內容

例子:

difference.$.user.$.otherinformation應該解釋爲包​​含:

difference 
difference.$ 
difference.$.user 
difference.$.user.$ 
difference.$.user.$.otherinformation 

我強烈的感覺,某種遞歸這裏要參與,但在方向上沒有進展呢。

下面是我的實現相同,但不幸的是,當我的子字符串匹配第一次發生的.$.時,它停止並且不會繼續檢查同一字符串中的其他出現.$.

我該如何最好地把這個關閉?

當前有缺陷的實現:

for(var i=0; i<array.length; i++){ 
    // next, replace all array field references with $ as that is what autoform's pick() requires 
    // /\.\d+\./g,".$." ==> replace globally .[number]. with .$.  
    array[i] = array[i].replace(/\.\d+\./g,".$."); 
     if(array[i].substring(0, array[i].lastIndexOf('.$.'))){ 
      console.log("Substring without .$. " + array[i].substring(0, array[i].indexOf('.$.'))); 
      console.log("Substring with .$ " + array[i].substring(0, array[i].indexOf('.$.')).concat(".$")); 
      array.push(array[i].substring(0, array[i].indexOf('.$.')).concat(".$")); 
      array.push(array[i].substring(0, array[i].indexOf('.$.'))); 
      } 
     } 
    // finally remove any duplicates if any 
    array = _.uniq(array); 

回答

1

一個功能單一的襯墊可以;

var array = ["authentication.$.order", "difference.$.user.$.otherinformation"], 
 
    result = array.reduce((r,s) => r.concat(s.split(".").reduce((p,c,i) => p.concat(i ? p[p.length-1] + "." + c : c), [])), []); 
 
console.log(result);

+0

迄今爲止就緊湊性而言最短的答案,但在可理解性方面複雜。你能否解釋這實際上是如何工作的? – blueren

+0

如果數組包含如下值:'「www.example.com。」'? – hindmost

+0

@ behindmost - 好問題,但我的初始數組永遠不會包含以'''''''結尾的內容,所以我認爲這是安全的。 – blueren

1

您可以使用數組循環中此功能。

var test = "difference.$.user.$.otherinformation"; 
 

 
function toArray(testString) { 
 
    var testArr = testString.split(".") 
 

 
    var tempString = ""; 
 
    var finalArray = []; 
 

 
    for (var i = 0; i < testArr.length; i++) { 
 

 
    var toTest = testArr[i]; 
 

 
    if (toTest == "$") { 
 
     tempString += ".$" 
 
    } else { 
 
     if (i != 0) { 
 
     tempString += "."; 
 
     } 
 

 
     tempString += toTest; 
 
    } 
 

 
    finalArray.push(tempString) 
 

 
    } 
 
    return finalArray; 
 
} 
 
console.log(toArray(test))

1

我用正則表達式表達抓住一切直到.$最後一次出現和切碎的它,直到有一無所有了。在最後反向。

let results = []; 
let found = true; 

const regex = /^(.*)\.\$/g; 
let str = `difference.\$.user.\$.otherinformation`; 
let m; 

results.push(str); 
while(found) { 
    found = false; 
    while ((m = regex.exec(str)) !== null) { 
     // This is necessary to avoid infinite loops with zero-width matches 
     if (m.index === regex.lastIndex) { 
      regex.lastIndex++; 
     } 

     if(m.length > 0) { 
      found = true; 
      results.push(m[0]); 
      str = m[1]; 
     } 
    } 
} 
results.push(str); 
results = results.reverse(); 
// Concat this onto another array and keep concatenating for the other strings 
console.log(results); 

你只需要在數組中循環這些,將結果存儲在一個臨時數組中,並將它們連接到一個最終數組上。

https://jsfiddle.net/9pa3hr46/

+0

這是有點過了......結果是:'''差異,差異$,$差異用戶$,$差異用戶$ otherinformation'。。。。。。 ''請注意'''difference。$。user''已被跳過。 – blueren

1

您可以使用reduce如下:

const dat = ["authentication.$.order", "difference.$.user.$.otherinformation"]; 

const ret = dat.reduce((acc, val) => { 
    const props = val.split('.'); 
    let concat = ''; 
    return acc.concat(props.reduce((acc1, prop) => { 
     concat+= (concat ? '.'+ prop : prop); 
     acc1.push(concat); 
     return acc1; 
    }, [])); 
}, []) 

console.log(ret); 
1

使用一個簡單的循環for象下面這樣:

var str = "difference.$.user.$.otherinformation"; 
 
var sub, initial = ""; 
 
var start = 0; 
 
var pos = str.indexOf('.'); 
 
for (; pos != -1; pos = str.indexOf('.', pos + 1)) { 
 
    sub = str.substring(start, pos); 
 
    console.log(initial + sub); 
 
    initial += sub; 
 
    start = pos; 
 
} 
 
console.log(str);

1

其實遞歸這個問題沒有必要。您可以改爲使用子循環的常規循環。

所有你需要的是:

  1. 分裂陣列成子在每種情況;
  2. 從這些子串構建一系列累加值;
  3. 用該系列替換數組的當前元素。

此外,爲了使替換正常工作,您必須以相反的順序迭代數組。順便說一句,在這種情況下,你不需要刪除數組中的重複。

因此,代碼應該是這樣的:

var array = ["authentication.$.order", "difference.$.user.$.otherinformation"]; 
 

 
var SEP = '.$.'; 
 
for (var i = array.length-1; i >= 0; i--){ 
 
    var v = array[i]; 
 
    var subs = v.replace(/\.\d+\./g, SEP).split(SEP) 
 
    if (subs.length <= 1) continue; 
 
    var acc = subs[0], elems = [acc]; 
 
    for (var n = subs.length-1, j = 0; j < n; j++) { 
 
     elems[j * 2 + 1] = (acc += SEP); 
 
     elems[j * 2 + 2] = (acc += subs[j]); 
 
    } 
 
    array.splice.apply(array, [i, 1].concat(elems)); 
 
} 
 
console.log(array);

+0

我把這段代碼片段放在了Chrome控制檯中,以便了解發生了什麼。但是,輸出似乎有點偏離要求。輸出:'',區別$。,difference。$。difference,difference。$。difference。$。,difference。$。difference。$。user''' – blueren

+1

@blueren對不起,我忘了初始化'elems'與'subs [0]'。現在它起作用 – hindmost

相關問題