在连续出现元素

时间:2016-01-16 19:47:17

标签: javascript arrays

我有一个像以下的JavaScript数组:

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

我想只获取在特定元素发生2次之后出现的数组元素。

即。在上面的数组中,我想获取后续'x', 'x'

之后的所有元素

所以我的输出应该是:

'p'
'b'

我有一个类似的解决方案:

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]);
    }
};

这满足了我的需求,但并不是那么通用。

例如。如果我必须检查3个后续发生的情况,那么我必须在{strong>如果中为myArray[i+2] == 'x'添加一个条件,依此类推。

有人能提供更好的方法来获取元素吗?

7 个答案:

答案 0 :(得分:5)

功能方式是使用递归。通过ES6传播,您几乎可以模仿真正“功能”语言的简洁性: - )

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));

答案 1 :(得分:3)

任何类似内容的通用直接方法。

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 :(得分:2)

您可以尝试遵循逻辑

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));

答案 3 :(得分:2)

您可以像这样创建一个额外的函数isItGood

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>

答案 4 :(得分:2)

这是一个简单的迭代解决方案。我们维护一个连续元素的数组consecutive。如果该数组的长度为2,则打印下一个元素并重置consecutive

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]];
    }
};

答案 5 :(得分:2)

尝试使用引用先前索引,当前索引,数组下一个索引

的变量来使用for循环

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;

答案 6 :(得分:2)

如果我不得不用Scala而不是JavaScript来编写它,我可以在一行中完成。 myArray.sliding(3).filter(l => l(0) == 'x' && l(1) == 'x').map(l => l(2))

所以我想如果我自己实现滑动功能,我可以在JS中以相同的方式做到这一点。 e.g。

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]);

这里唯一的缺点是,这比一个更迭代的方法运行得慢。但这只对非常大的阵列很重要。