Retrieving JavaScript array elements following the repeated appearance of a specific element

I have an array in JavaScript which looks like this:

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

I am interested in extracting elements from the array that come after two consecutive occurrences of a specific element.

For example, in the given array, I want to retrieve all elements that follow consecutive instances of 'x', 'x'

Therefore, the desired output would be:

'p'
'b'

Although I have found a solution to achieve this:

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

While this solution works, it is not very generic.

For instance, if I need to identify three consecutive occurrences, I would need to add another condition within the if statement for myArray[i+2] == 'x' and so forth.

Is there a more efficient approach to fetching these elements?

Answer №1

To tackle this problem in a functional manner, recursion is the way to go. By utilizing an ES6 spread operator, you can closely mimic the conciseness of a truly 'functional' language :-)

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

Answer №2

An efficient method for identifying specific patterns within an array.

function findPattern(array, pattern) {
    return array.reduce(function (result, element, index) {
        if (index >= pattern.length && pattern.every(function (p, j) {
            return p === array[index + j - pattern.length];
        })) {
            result.push(element);
        }
        return result;
    }, []);
}

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

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

Answer №3

One approach you could consider is as follows:

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;
  } // This generates the split string xx in the given example.
  var str = myArray.join(''); // Combines array items into a single string
  var array = str.split(splitStr); // Splits the string based on the split string
  var result = {};
  // Iterates over the array starting from index 1 to ignore the string before the split
  for (var i = 1 ; i < array.length; i++) { 
     if(array[i] !== "") {
        result[array[i].substring(0,1)] = ''; // Uses a map to prevent duplicate values
     }
  }
  
  return Object.keys(result); // Returns the keys
}

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

Answer №4

One way to tackle this issue is by using a simple iterative approach. We can keep track of consecutive elements in an array called consecutive. Whenever the length of this array reaches 2, we print out the next element and reset the consecutive array.

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

    // Check if the current element should be added to or reset the 'consecutive' array
    if (arr[i] === consecutive[0]) {
        consecutive.push(arr[i]);
    } else {
        consecutive = [arr[i]];
    }
};

Answer №5

To enhance your code, consider implementing a new function called 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]);
    // Display result without needing to open console
    document.getElementById('p').innerHTML+=("<br/>"+arr[i+total]);
}
<p id="p">Result: </p>

Answer №6

Converting this code from JavaScript to Scala would make it more concise, fitting into just a single line.

myArray.sliding(3).filter(l => l(0) == 'x' && l(1) == 'x').map(l => l(2))

If I wanted to achieve the same result in JavaScript without using the built-in sliding function, I could create my own implementation. For example:

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

The drawback of this approach is that it may run slower compared to a more iterative method. However, the performance impact is usually only noticeable with very large arrays.

Answer №7

Consider implementing a for loop that utilizes variables to access the previous index, current index, and next index of an array

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

for (var result = [], currentIdx = 0, prevIdx = currentIdx - 1, nextIdx = currentIdx + 1
    ; currentIdx < myArray.length - 1; currentIdx++, prevIdx++, nextIdx++) {
  if (myArray[currentIdx] === myArray[prevIdx]) result.push(myArray[nextIdx]);
};

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a layout with two rows of two buttons in HTML aligned to the right side while maintaining the left side's

I am currently working on designing a menu for my webpage that includes four buttons. My goal is to have two buttons displayed at the top of the page and two buttons displayed at the bottom. To achieve this, I have written the following CSS code: .navButt ...

Using a function to send multiple child data in Firebase

I am trying to figure out how to save data to a Firebase multi-child node structure: --Events ----Races -------Participants Below is some dummy data example that represents the type of data I need to store in Firebase: var dummyData = [ { ...

Angular's isteven-multi-select Component: A Versatile Selection Tool

Is it possible to utilize isteven-multi-select with ng-model? My goal is to have certain items appear as chosen when the page loads using the isteven-multi-select module. I've tried using ng-model in the HTML page to populate the isteven-multi-select ...

Tips for preventing JavaScript errors when making cross-domain requests using AJAX

Is there a way to prevent or handle JavaScript errors without causing the script to crash? Error message: No data returned $.ajax({ type : 'GET', dataType : 'jsonp', url : '//cvrapi.dk/api?search=dsfsdfsd&country= ...

What is the best way to retrieve an array element from outside a function?

Is there a way to access the distance and pos elements outside of the function in this code snippet? navigator.geolocation.getCurrentPosition(function(position) { var pos = { lat: position.coords.latitude, lng: position.coords.longit ...

Wait until the npm.load callback is returned before returning module.exports

I am currently facing a situation similar to the one depicted in this simplified example. main.js var settings = require('../settings.js'); console.log(settings.globalData); //undefined The settings.js file relies on an external module (npm) t ...

In MongoDB, rather than storing hashed passwords, it stores a "Promise" object

I've implemented bcrypt for hashing passwords and MongoDB for my database storage. Check out the code snippet below: export default function buildMakeUser({pwdHasher}) { return function makeUser({ username, email, passwor ...

Connect parent-child models with checkboxes

Currently, I am working on an application where I need to link checkboxes for a role-based menu. The challenge lies in dealing with parent-child checkboxes and ensuring that the values of checkboxes are checked based on user input 1, 1.1, 1.2, 2, 3. Despi ...

Location of chat icon in Dialogflow messenger

After successfully embedding the Dialogflow messenger in my website, I noticed that in mobile view, the chat icon is blocking the bottom navigation bar. You can refer to the screenshot here. Is there a way to reposition the chat icon higher on the page? I ...

Issue with Jquery - navigation menu scrolling

I'm struggling to understand why the second gallery isn't scrolling like the first one Check it out here: Here's the jQuery code that's responsible for making it work: $(function(){ var state = 0; var maxState = 7; var winWidth = $(&a ...

Kernighan and Ritchie's 2nd Edition, Illustration 1.9: Working with Character

I have a query regarding the getline() function and parameter definition in the code snippet below taken from K&R chapter 1.9: "Character arrays". Although I have replicated the code exactly as it appears, I encounter three errors upon compilation (as ...

Local variables in AngularJS across multiple Angular applications

Looking for a method to retain a local variable not affected by path or angular app changes. Attempted using $window.localStorage.set and get item, rootScope, and $window.variable with no success. ...

Adding elements to a JSON array in Javascript

Seeking assistance on updating a JSON array. var updatedData = { updatedValues: [{a:0,b:0}]}; updatedData.updatedValues.push({c:0}); This will result in: {updatedValues: [{a: 0, b: 0}, {c: 0}]} How can I modify the code so that "c" becomes part of ...

How do I retrieve the id of an event using a class descriptor within a JQuery Dialog constructor in Javascript?

As someone who is relatively new to JavaScript and jQuery, I must apologize in advance if my question seems basic. :) In a straightforward webpage, I am utilizing JQuery UI's Tabs and attempting to implement a double-click feature on the Tab names th ...

Adding a new column to a PySpark dataframe array

I am working with a Dataframe that has 2 columns | VPN | UPC | +--------+-----------------+ | 1 | [4,2] | | 2 | [1,2] | | null | [4,7] | My goal is to create a new column called "result" that combin ...

Improving the Sum of Pairs solution on Codewars

Seeking assistance in optimizing a solution for a problem that has already been identified. However, the existing code is not efficient when dealing with large arrays - view the problem on codeWars : Sum of Pairs Below is the current code snippet: var s ...

Retrieve the updated text content from a textarea using JavaScript/jQuery

For a beginner in javascript and jquery like me, I encountered an issue with a textarea element that has preset content. When I change the value on the site to "new" and click the "showme" button, the alert box displays the preset value instead of the new ...

Showing a heading based on a value in Angular: A Complete Guide

I am attempting to dynamically change the title based on the item's _id value. I have stored the item in the component. Here is the HTML code I am using: <h1 mat-dialog-title>{{item._id ? "Update" : "Add"}} animal</h1> Below is my dialog ...

Import MDX metadata in Next.js on the fly

I am currently utilizing Next.js to create a static blog site. Following the guidelines in Next.js documentation, I set up @next/mdx and successfully imported MDX statically using import MDXArticle from "@/app/(article)/2023/test-article/page.mdx&quo ...

Safari and iOS users may not experience the onended() event triggering

Code snippet performs as expected on Chrome 80.0 and Firefox 74.0 (OSX 10.14.6). However, when testing on OSX Safari 13.0.5 or iOS (using Chrome, Safari), the <div> element fails to turn blue, suggesting that the onended callback is not triggering. C ...