Get an array of N values(that are not present at "exclude" array) from an array X scanning in reverse and mutate the X array removing the added items

Viewed 69

I have an array named queue which will have some finite values in it. I want at max 2 records in the result array from the queue "scanning from the last index" where the values that are to be added result should not exist in the exclude array.

In short the conditions are:

  • The queue array needs to be scanned from right to left direction.
  • If the value scanned is not found in the exclude array, the value should be added to the result array.
  • When the result array thus obtained will have the length of maximum size N or when the end of the queue array is reached, the process should be terminated.
  • The queue array should be mutated in this process i.e. after adding the value to the result, the value should removed from the queue array(or can be removed at last it doesn't matter but it should be observed when the process terminates).

For an example:

let queue = [7, 9, 3, 4, 5];
let exclude = [4, 6, 10];
let resultCount = 2; // result's maximum length
let result = []; // will contain the result values

The expected end result looks like this:

result = [5, 3]; // can be in any order
queue = [7, 9, 4]; // mutated queue

Here, scanning from the last index, the value 5 is found unique and added to the result array but value 4 is skipped because it exists on the exclude array. Then the value 3 is found unique and added to the result array. Since the maximum size of the result array, 2 is reached i.e. [5, 3], the process is terminated. The matching values will also be removed from the queue array leaving the array [7, 9, 4] at the end of the process.

Is there any way achieve this behaviour?

2 Answers

Using a while loop and looping through your queue backwars until either you reach the 0th index or you reach your resultsCount, you can check whether each queue element is in your exclude array. If it isn't, you can add this element to your result array using .push(), and then remove it from the queue using .splice(index, 1).

See example below:

let queue = [7, 9, 3, 4, 5];
let exclude = [4, 6, 10];
let resultCount = 2; // result's maximum length
let result = []; // will contain the result values

let i = queue.length-1; // get last index in queue
while(result.length < resultCount && i >= 0) { // keep looping your queue array until you either reach your resultsCount or you get to index -1 
  const curr = queue[i]; // get the current queue item
  if(!exclude.includes(curr)) { // if the current item is not inside your exclude array...
    result.push(curr); // push the current element into the resulting array
    queue.splice(i, 1); // remove it from the queue
  }
  i--; // decrement i
}
console.log(result);
console.log(queue);

You can also use a Set for your exclude array if you have many elements in it to help with efficiency.

Using .filter() can also be nice, but it creates new arrays rather than modifying in-place:

let queue = [7, 9, 3, 4, 5];
const exclude = new Set([4, 6, 10]);
const resultCount = 2; // result's maximum length

const result = queue.filter(n => !exclude.has(n)).slice(resultCount);
queue = queue.filter(n => !result.includes(n));
console.log(result);
console.log(queue);

Here is a way to step backwards through an array with a for loop.

let queue = [7, 9, 3, 4, 5];
let exclude = [4, 6, 10];
let resultCount = 2; // result's maximum length
let result = []; // will contain the result values

// Step backwards through the array
for(let i = queue.length-1; i >= 0; i--) {
  // If the number is not in the exclude list
  if(!exclude.includes(queue[i])){
    // Add to the array
    result.push(queue[i])
    // Remove from queue array.
    queue.splice(i, 1);
  }
  if(result.length >= resultCount) {
    // End the for loop
    break;
  }
}

console.log(queue);
console.log(result);

Related