Reverse filtered array Angular

Viewed 380

I have an array like ['a','b','c','d','e','f'] and I want to reverse only a part that I filter previously, for example I filter and I get ['c','d','e'] and I do reverse and the final result that I expected is ['a','b','e','d','c','f'].

I've tried to do array.slice().filter(condition).reverse(), and another solutions from stackoverflow but no one worked for me.

Any idea?

4 Answers

if you know the starting index and length of sub-array you want to reverse

const arr = ['a','b','c','d','e','f'];

function reverse(arr, i, j){
    while(i <j){
      const temp = arr[i]
      arr[i]=arr[j];
      arr[j]=temp;
      i++;
      j--;
    }
   return arr;
}

const result = reverse(arr, 2, 4) 
console.log(result)  //  ["a", "b", "e", "d", "c", "f"]

the code above will solve your problem in time complexity of O(n)

Just a quick solution to your problem is to get an array of the indexes you've filtered and the replace those indexes with the reversed value. See this example:

const array = ['a', 'b', 'c', 'd', 'e', 'f'];
const indexHolder = [];

const filterValues = ['c', 'd', 'e']

const filtered = array
  .slice()
  .filter((item, index) => {
    const shouldFilter = filterValues.includes(item);

    if (shouldFilter) {
      indexHolder.push(index);
    }

    return shouldFilter;
  })
  .reverse();

const result = array.map((item, index) => {
  const foundIndex = indexHolder.indexOf(index);
  if (foundIndex >= 0) {
    // found, so we need the reversed
    return filtered[indexHolder.indexOf(index)];
  }

  return item;
});
console.log(result);

One quick solution is going through the array twice. Once to clear the boxes you need, once to fill them in reverse.

var x = ['a', 'b', 'c', 'd', 'e', 'f'];
var cond = ['b', 'd', 'e'];
var filtered = [];

for (let i = 0; i < x.length; i++) {
  if (cond.indexOf(x[i]) !== -1) {
    filtered.push(x[i]);
    x[i] = null;
  }
}
var counter = 0;
for (let i = x.length; i >=0; i--) {
  if (x[i] === null) {
    x[i] = filtered[counter];
    counter++;
  }
}

console.log(x);

My answer is basically a mimic of Bas with some different formatting in case you want to use functions. But all credit goes to Bas for doing the leg work for my solution.

ngOnInit() {
   const array = ['a', 'b', 'c', 'd', 'e', 'f'];
   const filterValues = ['c', 'd', 'e']

   console.log(this.resultFn(array, filterValues));
}

resultFn(array, filterValues) {
  const indexHolder = [];
  const filtered = this.filteredFn(array, filterValues, indexHolder);

  return array.map((item, index) => {
    const foundIndex = indexHolder.indexOf(index);
    if (foundIndex >= 0) {
      // found, so we need the reversed
      return filtered[indexHolder.indexOf(index)];
    }

    return item;
  });
}

filteredFn(array, filterValues, indexHolder) {
  return array
    .slice()
    .filter((item, index) => {
      const shouldFilter = filterValues.includes(item);

      if (shouldFilter) {
        indexHolder.push(index);
      }

      return shouldFilter;
    })
    .reverse();
}
Related