2015-10-02 85 views
0

我目前正在進行Codewars挑戰http://www.codewars.com/kata/your-order-please。任務是取一個字符串並根據字符串的每個單詞中找到的值對單詞進行重新排序,例如:「is2 Thi1s T4est 3a」該函數應該返回「Thi1s is2 3a T4est」。JavaScript循環效率/性能

我寫了成功通過提供的所有測試,並返回正確的字符串的解決方案。 https://jsfiddle.net/louisstanard/5hygz6wb/

function order(words){ 
    var ordered = []; 
    var arr = words.split(' '); 
    var n = 1; 
    while (n <= arr.length) { 
    for (var i = 0; i < arr.length; i++) { 
     var stringArr = arr[i].split(''); 
     stringArr.forEach(function(currentValue, index) { 
     if (parseInt(currentValue) === n) { 
      ordered.push(arr[i]); 
      n++; 
     } 
     }); 
    } 
    } 
    return ordered.join(' '); 
} 

我的問題是,當我試圖提交的解決方案,我收到一個錯誤說「過程被終止。花了超過6000ms完成」。我選擇使用while循環,因爲我想繼續遍歷字符串中的每個單詞來查找數字,直到我構建了一個長度與原始數組長度相同的新數組。

我是新來編寫更好的性能JS,但我知道,while循環(也可能一個嵌套了一會兒內)可能會非常昂貴的操作。有人知道爲什麼這可能需要很長時間才能運行嗎?我沒有看到任何明顯的性能問題嗎?或者可能是一個更好的方法?謝謝!

+2

這可能是http://codereview.stackexchange.com/ – 1252748

+1

@thomas我忘了代碼審查社區更適合 - 你是正確的,這將是一個更適合。下次我會在那裏發帖。謝謝! –

回答

0

這是另一種方式來做到這一點:

function order(words){ 
    return words 
    .split(' ') 
    .sort(function(wordA, wordB) { 
     var numA = +(wordA.match(/\d+/g)[0]); 
     var numB = +(wordB.match(/\d+/g)[0]); 
     return numA - numB; 
    }) 
    .join(' '); 
} 
+0

提供了另一種方法來解決問題 – charlietfl

+0

OP也詢問是否存在:「也許更好的方法?」。我給出了一個清晰,簡潔並且循環時間不超過6000毫秒的問題,這是他的問題。 – TbWill4321

+0

好的...夠公平的...只是看着爲什麼一部分。 – charlietfl

0

看看更新了自己的Fiddle here。在我的Chrome瀏覽器中,顯示的速度比原始快。

function orderNew(words){ 
    var ordered = []; 
    var arr = words.split(' '); 

    arr.forEach(function(item, index){ 
     var match = /\d+/.exec(item); 
     ordered[parseInt(match[0])] = item; 
    }); 
    return ordered.join(' '); 
} 
0

因爲你不需要計算的很多您的代碼運行緩慢:

  • 你不緩存你的兩個數組的長度,所以每次迭代中,你再次檢查長度。
  • 你有3個循環,其中一個循環就足夠了。
  • 你檢查的話每一個字母,而parseInt函數(字10)已經返回字內的第一個數字,所以在循環的字母是沒用的。
  • 你的while循環和第一個for循環基本上都是這樣做的,因爲它們都從0開始,並以原始字符串包含的單詞量結束。
  • 你把你的結果推到一個數組,而不是僅僅設置有序[i] = arr [i]。
  • 您的for循環不包含中斷,所以即使您已經找到正確的結果(本例中爲數字),您仍然會繼續循環。
  • 試圖建立一個新的陣列,直到它具有原始數組的長度的邏輯是有缺陷的,因爲如果你完成循環,新的數組總會有原來的長度,如果你的代碼是正確的。

因此,簡而言之,是的,使用其他ppl發佈的技術之一會更高效,因爲代碼更加優化並且不包含冗餘邏輯。

+0

感謝您深入分析@Shilly!非常感激。 –