2015-10-02 87 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!非常感激。 –