首先,你需要向後迭代,以確保你最終不會覆蓋以前所做的替換,但是,在我的例子中,它並不重要,因爲字符串在最後一次被重新組裝。
// > interpolateOnIndices([[5,9], [23,27]], "eggs eggs spam and ham spam");
// < 'eggs <span>eggs</span> spam and ham <span>spam</span>'
function interpolateOnIndices(indices, string) {
"use strict";
var i, pair, position = string.length,
len = indices.length - 1, buffer = [];
for (i = len; i >= 0; i -= 1) {
pair = indices[i];
buffer.unshift("<span>",
string.substring(pair[0], pair[1]),
"</span>",
string.substring(pair[1], position));
position = pair[0];
}
buffer.unshift(string.substr(0, position));
return buffer.join("");
}
這是一個更好一點,然後用splice
ING的例子,因爲它不會產生額外的陣列(拼接本身就會創造更多的陣列)。在其他函數中反覆使用映射和創建函數是一個特定的內存管理器,但它運行速度不是很快......雖然它稍微短一些。
對於大型字符串連接,在理論上,應該爲您提供優於多個連接的優勢,因爲內存分配將只進行一次,而不是隨後丟棄一半的字符串。當然,除非您正在處理大量數據,否則所有這些都不必關心您。
編輯:
因爲我有太多的時間在我的手上,我決定做一個測試,看看如何變化將比較在更大的(但相當現實)的數據集,下面是我的測試代碼的一些結果...
function interpolateOnIndices(indices, string) {
"use strict";
var i, pair, position = string.length,
len = indices.length - 1, buffer = [];
for (i = len; i >= 0; i -= 1) {
pair = indices[i];
buffer.unshift("<span>",
string.substring(pair[0], pair[1]),
"</span>",
string.substring(pair[1], position));
position = pair[0];
}
buffer.unshift(string.substr(0, position));
return buffer.join("");
}
function indexWrap(indexArr, str) {
var chars = str.split("");
for(var i = 0; i < indexArr.length; i++) {
var indexes = indexArr[i];
if(chars[indexes[0]] && chars[indexes[1]]){
chars.splice(indexes[0], 0, "<span>");
chars.splice(indexes[1], 0, "</span>");
}
}
return chars.join("");
}
function replaceOffset(str, offs, tag) {
tag = tag || "span";
offs.reverse().forEach(
function(v) {
str = str.replace(
new RegExp("(.{" + v[0] + "})(.{" + (v[1] - v[0]) + "})"),
"$1<" + tag + ">$2</" + tag + ">"
);
});
return str;
}
function generateLongString(pattern, times) {
"use strict";
var buffer = new Array(times);
while (times >= 0) {
buffer[times] = pattern;
times -= 1;
}
return buffer.join("");
}
function generateIndices(pattern, times, step) {
"use strict";
var buffer = pattern.concat(), block = pattern.concat();
while (times >= 0) {
block = block.concat();
block[0] += step;
block[1] += step;
buffer = buffer.concat(block);
times -= 1;
}
return buffer;
}
var longString = generateLongString("eggs eggs spam and ham spam", 100);
var indices = generateIndices([[5,9], [23,27]], 100,
"eggs eggs spam and ham spam".length);
function speedTest(thunk, times) {
"use strict";
var start = new Date();
while (times >= 0) {
thunk();
times -= 1;
}
return new Date() - start;
}
speedTest(
function() {
replaceOffset(longString, indices, "span"); },
100); // 1926
speedTest(
function() {
indexWrap(indices, longString); },
100); // 559
speedTest(
function() {
interpolateOnIndices(indices, longString); },
100); // 16
測試對V8(Node.js的)在AMD64的Linux(FC-17)。
我沒有測試的不確定的答案,因爲我不希望加載該庫,特別是因此它不會做任何事情,這個測試非常有用。我可以想象它會在兩者之間以及elclanrs的變體之間出現,更多的是對elclanrs的回答。
我想你需要一個分析器,而不是一個簡單的與string.replace()方法。你當然可以用string.replace()來做到這一點,但它會變得很慢。一次讀取一個字符,標記字符串,對數組進行處理並生成輸出字符串可能會更有效。 – jrista
感謝@jrista,也許是這樣的:'升= s.split( '')''然後L [5] = 「」 + A [5]'同樣地,對於每個偏移對每個元素,然後加入結果?我會嘗試的。 – jjon
這就是類似於我的反應居然 – anson