2016-01-16 33 views
8

Tôi có một mảng JavaScript như:tìm nạp JavaScript phần tử mảng sau khi xảy ra liên tiếp của một phần tử

var myArray = ['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x']; 

Tôi muốn lấy chỉ những yếu tố của mảng mà đến sau 2 lần xuất hiện hậu quả của một yếu tố cụ thể.

tức là trong mảng trên, tôi muốn lấy tất cả các yếu tố đó đến sau khi quả 'x', 'x'

Vì vậy, đầu ra của tôi nên là:

'p' 
'b' 

tôi có một giải pháp như:

var arrLength = myArray.length; 
for (var i = 0; i < arrLength; i++) { 
    if(i+2 < arrLength && myArray[i] == 'x' && myArray[i+1] == 'x') { 
     console.log(myArray[i+2]); 
    } 
}; 

Điều này đáp ứng nhu cầu của tôi, nhưng nó không phải là quá chung chung.

Ví dụ: nếu tôi phải kiểm tra 3 lần xảy ra hậu quả, thì tôi phải thêm một điều kiện bên trong nếu cho myArray[i+2] == 'x' và cứ như vậy.

Có ai có thể cung cấp cách tốt hơn để tìm nạp các phần tử không?

+2

Nếu bạn có 4 '' x'' thì sao? Nếu thứ 3 được tìm nạp? Do các 3rd và 4rt lấy mục sau đây? – Oriol

+1

Các phần tử mảng luôn là các chữ cái đơn? Đây thực chất là một vấn đề chuỗi (với nhiều giải pháp tốt và hiệu quả), mặc dù không có giải pháp nào được thực thi trên 'Array' – Bergi

+0

@Bergi, tôi muốn một giải pháp chung để mảng này có thể chứa một chữ cái hoặc có thể là một chuỗi . –

Trả lời

5

Cách chức năng sẽ là sử dụng đệ quy. Với sự lây lan của ES6, bạn có thể mô phỏng được sự terseness của một ngôn ngữ thực sự 'chức năng' :-)

var myArray = ['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x']; 

function reducer(acc, xs) { 
    if (xs.length > 2) { 
     if (xs[0] === xs[1]) { 
      // add the third element to accumulator 
      // remove first three elements from xs 
      // return reducer([xs[2], ...acc], xs.slice(3)); 
      // or per Nina's question below 
      return reducer([xs[2], ...acc], xs.slice(1)); 
     } else { 
      // remove first element from xs and recurse 
      return reducer(acc, xs.slice(1)) 
     } 
    } else { 
     return acc; 
    } 
} 

console.log(reducer([], myArray)); 
+0

ok, tôi thích chức năng hơn bắt buộc –

+0

Đệ quy là một cơ chế tái phát nhiều trong các ngôn ngữ chức năng. Và mã này thực sự mô phỏng lập trình hàm rất tốt - không có mã thủ tục/mệnh lệnh ngoại trừ 'slice()', có thể được sao chép bằng ngôn ngữ chức năng. – Purag

+0

hãy kiểm tra mảng này: '['a', 'x', 'b', 'x', 'x', 'x', 'p', 'y', 'x', 'x', 'b ',' x ',' x '] 'với tripple'' x'', kết quả mong đợi: '['x', 'p', 'b']' –

2

Bạn có thể thử sau Logic

var myArray = ['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x']; 
 

 
function search(ch, times) { 
 
    var splitStr = ""; 
 
    for(var i = 0; i < times; i++) { 
 
    splitStr += ch; 
 
    } // Generate the split string xx in the above case. 
 
    var str = myArray.join(''); // Join array items into a string 
 
    var array = str.split(splitStr); // Split the string based on split string 
 
    var result = {}; 
 
    // iterate on the array starting from index 1 as at index 0 will be string before split str 
 
    for (var i = 1 ; i < array.length; i++) { 
 
    if(array[i] !== "") { 
 
     result[array[i].substring(0,1)] = ''; // A map in order to avoid duplicate values 
 
    } 
 
    } 
 
    
 
    return Object.keys(result); // return the keys 
 
} 
 

 
console.dir(search('x',2));

2

Bạn có thể tạo một chức năng thêm isItGood như thế này:

var myArray = ['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x']; 
 
var arrLength = myArray.length; 
 
for (var i = 0; i < arrLength; i++) { 
 
    isItGood(myArray, i, 'x', 2); 
 
}; 
 

 
function isItGood(arr, i, elem, total) { 
 
    for (var j = 0 ; j < total ; j++) { 
 
     if (i + total >= arr.length || arr[i+j] != elem) { 
 
      return; 
 
     } 
 
    } 
 
    console.log(arr[i+total]); 
 
    // just to see the result (no need to open a console) 
 
    document.getElementById('p').innerHTML+=("<br/>"+arr[i+total]); 
 
}
<p id="p">Result: </p>

3

Một cách tiếp cận chung về phía trước cho mọi nội dung có thể so sánh.

function getParts(array, pattern) { 
 
    return array.reduce(function (r, a, i) { 
 
     i >= pattern.length && pattern.every(function (b, j) { 
 
      return b === array[i + j - pattern.length]; 
 
     }) && r.push(a); 
 
     return r; 
 
    }, []); 
 
} 
 

 
function p(o) { 
 
    document.write('<pre>' + JSON.stringify(o, 0, 4) + '</pre>'); 
 
} 
 

 
p(getParts(['a', 'x', 'x', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x'], ['x', 'x'])); 
 
p(getParts(['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x'], ['a', 'x', 'b'])); 
 
p(getParts(['a', 'b', 'c', 'd', 'z', 'y', 'a', 'b', 'c', 'd', 'x', 'x'], ['a', 'b', 'c', 'd'])); 
 
p(getParts([41, 23, 3, 7, 8, 11, 56, 33, 7, 8, 11, 2, 5], [7, 8, 11]));

2

Dưới đây là một giải pháp lặp đi lặp lại đơn giản. Chúng tôi duy trì một mảng consecutive các phần tử liên tiếp. Nếu mảng đó có chiều dài 2, thì phần tử tiếp theo sẽ được in và consecutive được đặt lại.

var arr = ['a', 'x', 'b', 'x', 'x', 'p', 'y', 'x', 'x', 'b', 'x', 'x']; 

var REPEATS_NEEDED = 2; 

var consecutive = [arr[0]]; 
for (var i = 1; i < arr.length; i++) { 
    if (consecutive.length === REPEATS_NEEDED) { 
     console.log(arr[i]); 
     consecutive = [arr[i]]; 
     continue; 
    } 

    // either add to or reset 'consecutive' 
    if (arr[i] === consecutive[0]) { 
     consecutive.push(arr[i]); 
    } else { 
     consecutive = [arr[i]]; 
    } 
}; 
2

Hãy thử sử dụng for vòng lặp sử dụng các biến tham khảo chỉ số trước đó, chỉ số hiện tại, chỉ số tiếp theo của mảng

var myArray = ["a", "x", "b", "x", "x", "p", "y", "x", "x", "b", "x", "x"]; 
 

 
for (var res = [], curr = 0, prev = curr - 1, match = curr + 1 
 
    ; curr < myArray.length - 1; curr++, prev++, match++) { 
 
    if (myArray[curr] === myArray[prev]) res.push(myArray[match]); 
 
}; 
 

 
console.log(res); 
 
document.body.textContent = res;

2

Nếu tôi đã phải viết những dòng này trong Scala thay vì JavaScript tôi có thể chỉ cần làm điều đó trong một dòng. myArray.sliding(3).filter(l => l(0) == 'x' && l(1) == 'x').map(l => l(2))

Vì vậy, tôi đoán tôi có thể làm theo cách tương tự trong JS nếu tôi tự thực hiện chức năng trượt. ví dụ:

function sliding(array, n, step) { 
    if(!step) step = 1; 
    var r = []; 
    for(var i = 0; i < array.length - n + 1; i += step) { 
    r.push(array.slice(i, i + n)); 
    } 
    return r; 
} 
var result = sliding(myArray, 3).filter(l => l[0] === "x" && l[1] === "x").map(l => l[2]); 

Nhược điểm duy nhất ở đây là điều này chạy chậm hơn một cách tiếp cận lặp lại nhiều hơn. Nhưng điều đó chỉ quan trọng đối với các mảng rất lớn.

Các vấn đề liên quan