1

I have an array of object [{a:1},{a:2},{a:3},{a:4},{a:5}].

I want to find index of {a:3} and remove all next elements from index of {a:3}.

Result should look like [{a:1},{a:2},{a:3}] and removed elements will be {a:4},{a:5}.

bguiz
  • 27,371
  • 47
  • 154
  • 243
  • 1
    do you want a new array or keeping the old without unwanted? please add the wanted result and the code, you tried. – Nina Scholz Feb 10 '21 at 08:00

2 Answers2

3

One line vanilla JS with slice and findIndex

const data = [{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }, { a: 5 }];

const res = data.slice(
  0,
  data.findIndex((el) => JSON.stringify(el) === JSON.stringify({ a: 3 })) + 1
);

console.log(res);
hgb123
  • 13,869
  • 3
  • 20
  • 38
  • I don't want to compare it with array element value like `a===3` . I really need to be done with indexes of an array – Shopify Guy Feb 10 '21 at 07:34
  • @ShopifyGuy hmm, so you might need deep object comparision, I updated the answer with a JSON.stringify solution – hgb123 Feb 10 '21 at 07:36
  • The `JSON.stringify` method is inefficient and might not work in some cases, etc. See [this](https://stackoverflow.com/a/36012146/8376184) – FZs Feb 10 '21 at 08:01
3

You can use Array#findIndex() to find that object by its number, or Array#indexOf() if you have a reference to it.

Then, you can either set the array's length (mutating) or use Array#slice() (not mutating), to reduce its length:

const array = [{a:1},{a:2},{a:3},{a:4},{a:5}]

const i = array.findIndex(({a}) => a === 3)

const arrayCopy = array.slice(0, i + 1)
//or:
array.length = i + 1

console.log(i)
console.log(arrayCopy)
console.log(array)

Or with Array#indexOf():

//If you have a reference from somewhere:
const ref = {a:3}

const array = [{a:1},{a:2},ref,{a:4},{a:5}]

const i = array.indexOf(ref)

const arrayCopy = array.slice(0, i + 1)
//or:
array.length = i + 1

console.log(i)
console.log(arrayCopy)
console.log(array)

Alternatively, if you don't have a reference, but it's guaranteed that the array is sorted, you can use a binary search, that makes this much faster for large arrays:

function binarySearch(array, target, cb) {
  let start = 0, end = array.length
  while(start < end){
    const middle = ((end - start - 1) >>> 1)  + start
    const middleVal = cb(array[middle], middle)
    if(middleVal === target) return middle
    if(middleVal < target)
      start = middle + 1
    else
      end = middle
  }
  return -1
};

const array = [{a:1},{a:2},{a:3},{a:4},{a:5}]

const i = binarySearch(array, 3, ({a}) => a)

const arrayCopy = array.slice(0, i + 1)
//or:
array.length = i + 1

console.log(i)
console.log(arrayCopy)
console.log(array)
FZs
  • 16,581
  • 13
  • 41
  • 50