2015-05-02 14 views
5

Thực sự, khá nhiều những gì tiêu đề nói.Giới hạn thời gian mà .split() tách ra, thay vì cắt ngắn mảng kết quả

Giả sử bạn có chuỗi này:

var theString = "a=b=c=d"; 

Bây giờ, khi bạn chạy theString.split("=") kết quả là ["a", "b", "c", "d"] như mong đợi. Và, tất nhiên, khi bạn chạy theString.split("=", 2) bạn nhận được ["a", "b"], sau khi đọc the MDN page for String#split() có ý nghĩa với tôi.

Tuy nhiên, hành vi của tôi đang tìm là giống như Java String#split(): Thay vì xây dựng mảng bình thường, sau đó trả lại n yếu tố đầu tiên, nó được xây dựng một loạt các là người đầu tiên n-1 trận đấu, sau đó thêm tất cả các ký tự còn lại làm phần tử cuối cùng của mảng. Xem the relevant docs để có mô tả tốt hơn.

Làm cách nào để có hiệu ứng này trong Javascript?

Tôi đang tìm câu trả lời có hiệu suất tốt nhất hoạt động như triển khai Java, mặc dù cách thực tế hoạt động có thể khác.

Tôi đã đăng nỗ lực của mình, nhưng tôi không biết cách viết về điều này.

Trả lời

6

Nếu bạn muốn tương đương chính xác của việc thực hiện Java (không kiểm tra lỗi hoặc các điều khoản bảo vệ vv):

function split(str, sep, n) { 
    var out = []; 

    while(n--) out.push(str.slice(sep.lastIndex, sep.exec(str).index)); 

    out.push(str.slice(sep.lastIndex)); 
    return out; 
} 

console.log(split("a=b=c=d", /=/g, 2)); // ['a', 'b', 'c=d'] 

này có lợi ích bổ sung không tính toán phân chia hoàn thành trước, như bạn đã đề cập trong câu hỏi của bạn .

+0

Bạn có thể thêm giải thích nhanh về cách hoạt động của tính năng này không? –

+0

@QPaysTaxes Tôi lặp lại "giới hạn" số lần và mỗi lần lặp lại, tôi sử dụng regex trạng thái để tìm lần xuất hiện tiếp theo của ký tự tách. Các regex nhớ nơi trận đấu cuối cùng của nó là, và một khi nó thực hiện tôi biết nơi trận đấu tiếp theo là. Tôi thêm lát cắt giữa hai vị trí đó trên mỗi lần lặp. Bên ngoài vòng lặp, tôi thêm lát chuỗi giữa kết hợp regex cuối cùng và kết thúc chuỗi. –

+2

Và kể từ khi OP hỏi về hiệu suất - việc triển khai này nhanh gấp đôi (trong Chrome) như hai phương pháp khác. Làm tôi ngạc nhiên! –

3

Tôi muốn sử dụng một cái gì đó như thế này:

function JavaSplit(string,separator,n) { 
    var split = string.split(separator); 
    if (split.length <= n) 
     return split; 
    var out = split.slice(0,n-1); 
    out.push(split.slice(n-1).join(separator)); 
    return out; 
} 

Những gì chúng ta đang làm ở đây là:

  1. tách chuỗi hoàn toàn
  2. Lấy n-1 yếu tố đầu tiên, như mô tả .
  3. Nối lại các phần tử còn lại.
  4. Nối chúng vào mảng từ bước 2 và quay lại.

Một cách hợp lý có thể nghĩ bạn có thể kết hợp tất cả các cuộc gọi đó lại với nhau, nhưng .push() thay đổi mảng thay vì trả về một mảng mới. Nó cũng dễ dàng hơn một chút để bạn làm theo cách này. thực hiện tốt

+2

hi, có lẽ bạn cần phải kiểm tra độ dài kết quả phân chia lớn hơn n trước khi thực hiện lát, nếu không chỉ trả lại kết quả phân chia. – Surely

+0

Điểm tốt; thêm. –

+0

Tôi thích cái này vì sự đơn giản của nó, nhưng tôi chấp nhận cái kia bởi vì (theo như tôi có thể nói mà không có điểm chuẩn) nó hiệu quả hơn. –

2

Một hơn:

function split(s, separator, limit) { 
    // split the initial string using limit 
    var arr = s.split(separator, limit); 
    // get the rest of the string... 
    var left = s.substring(arr.join(separator).length + separator.length); 
    // and append it to the array 
    arr.push(left); 
    return arr; 
} 

Fiddle là here.

+0

Mặc dù tôi không hoàn toàn chắc chắn về 'length + 1' - tôi đoán nó phụ thuộc vào yêu cầu của bạn - cho dù bạn muốn có một' tách 'hàng đầu trong phần tử cuối cùng hay không. –

+0

Thay thế '+ 1' bằng' + separator.length', trong trường hợp bạn nhận được dấu phân tách multicharacter. –

0

Bạn đang tìm kiếm thứ gì đó gần với explode của PHP?

Dưới đây là một phương pháp tôi đã nghĩ ra:

String.prototype.explode = function(sep, n) { 
    var arr = this.split(sep, n) 
    if (arr[n-1] != undefined) arr[n-1] += this.substring(arr.join(' ').length); 
    return arr; 
} 

Phương pháp này chia tách các chuỗi như bình thường, xác định nếu chúng ta đã đạt giới hạn của chúng tôi, và sử dụng substring để thêm văn bản ngoài chia cuối cùng của chúng tôi (chúng ta có thể trực tiếp truy cập vào các offset của ký tự đầu tiên vượt qua sự chia rẽ cuối bởi nhận được length của một join sử dụng trên mảng với bất kỳ nhân vật duy nhất là tách)

phương pháp này được sử dụng giống như split:

012.
str = 'my/uri/needs/to/be/split'; 
splitResult = str.split('/', 4); 
explodeResult = str.explode('/', 4); 
console.log(splitResult); 
console.log(explodeResult); 

// The following will be written to the console: 
// splitResult: ["my", "uri", "needs", "to"] 
// explodeResult: ["my", "uri", "needs", "to/be/split"] 

Và tất nhiên, điều này có thể được quay như một chức năng quá:

function explode(str, sep, n) { 
    var arr = str.split(sep, n) 
    if (arr[n-1] != undefined) arr[n-1] += this.substring(arr.join(' ').length); 
    return arr; 
} 

str = 'my/uri/needs/to/be/split'; 
explodeResult = explode(str, '/', 4); 
Các vấn đề liên quan