Angular - как уменьшить массив, основываясь на определенных c проверках? - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть упорядоченный массив, который я получаю из БД, который выглядит примерно так:

     let myArray = [      
        {month: 1, visible: true},
        {month: 2, visible: false}, 
        {month: 3, visible: true}, 
        {month: 4, visible: false},
        {month: 5, visible: false}, 
        {month: 6, visible: true},
        {month: 7, visible: true},
        {month: 8, visible: false}, 
        {month: 9, visible: true}, 
        {month: 10, visible: false},
        {month: 11, visible: false},
        {month: 12, visible: false}
      ];

, что мне нужно сделать, это уменьшить его до нового массива, где первый объект будет быть первым month, обладающим свойством visible = true, тогда все последние месяцы, которые имеют month = true

, будут занимать все месяцы; это означает, что месяцы будут игнорироваться, только если они не находятся в последовательности, поэтому, если они не создают пробелы.

В моем примере выше, он будет возвращать все объекты, кроме последнего 3 (10, 11, 12), потому что они находятся вне последовательности, которая создается первым TRUE и последним TRUE (в данном случае month 1 и month 9)

Надеюсь, я дал понять, как мне завершить мой метод limit ()?

myArray = myArray
    .sort((a, b) => a.month - b.month)
    .reduce((arr, current, idx) => {

      return arr;
    }, []);            

Желаемый результат:

 let myArray = [      
            {month: 1, visible: true},
            {month: 2, visible: false}, 
            {month: 3, visible: true}, 
            {month: 4, visible: false},
            {month: 5, visible: false}, 
            {month: 6, visible: true},
            {month: 7, visible: true},
            {month: 8, visible: false}, 
            {month: 9, visible: true}
];

Ответы [ 2 ]

2 голосов
/ 21 февраля 2020

Найти начальную позицию тривиально, но найти конечную позицию немного сложнее.

Я бы выбрал такой подход:

  1. найти первый индекс с условием соответствия
  2. найти последний индекс с подходящим условием
  3. вернуть фрагмент от первого до последнего
// accept an array of type T and a predicate
// the predicate indicates which items define the inner range
// the predicate is a callback - a function - that accepts an argument of type T and returns a boolean

private filterInner<T>(arr: T[], predicate: (t: T) => boolean): T[] {

  // use findIndex to find the first matching index for the predicate

  const first = arr.findIndex(predicate);
  if (first === -1) {
    // no matching items in array
    return [];
  }


  // loop backwards to find the last matching index for the predicate

  let last = first;
  for (let i = arr.length - 1; i >= first; i--) {
    if (predicate(arr[i]) === true) {
      last = i;
      break;
    }
  }


  // return the portion of the range between the two indexes (inclusive)
  return arr.slice(first, last + 1);
}

В вашем случае вы бы использовали его следующим образом:

myArray = myArray.sort((a, b) => a.month - b.month);
const filtered = this  
  .filterInner(myArray, x => x.visible);

DEMO: https://stackblitz.com/edit/angular-xrpsct

Дополнительное чтение

Некоторые дополнительные чтения, если некоторые из этих методов являются новыми для вас:

Javascript эквивалент

Это обычный javascript эквивалент без шума Typescript.

function filterContiguous(arr, predicate) {
  const first = arr.findIndex(predicate);
  if (first === -1) {
    // no matching items in array
    return [];
  }

  let last = first;
  for (let i = arr.length - 1; i >= first; i--) {
    if (predicate(arr[i]) === true) {
      last = i;
      break;
    }
  }

  return arr.slice(first, last + 1);
}
0 голосов
/ 21 февраля 2020

Вы можете найти индекс до тех пор, пока он не будет разрезан, а затем просто взять этот массив:

const findMaxIndex = arr => {
    let prev = 0;
    for (let index = arr.length - 1; index >= 0; index--) {
        prev = index - 1;
        if (arr[index].visible == false && arr[prev].visible !=  false)
          return index;
    }
    return -1;
};

console.log(myArray.slice(0, findMaxIndex(myArray)));

Пример:

let myArray = [
        {month: 1, visible: true},
        {month: 2, visible: false},
        {month: 3, visible: true},
        {month: 4, visible: false},
        {month: 5, visible: false},
        {month: 6, visible: true},
        {month: 7, visible: true},
        {month: 8, visible: false},
        {month: 9, visible: true},
        {month: 10, visible: false},
        {month: 11, visible: false},
        {month: 12, visible: false}
];

let maxIndex = 0;

const findMaxIndex = arr => {
    let prev = 0;
    for (let index = arr.length - 1; index >= 0; index--) {
        prev = index - 1;
        if (arr[index].visible == false && arr[prev].visible !=  false)
          return index;
    }
    return -1;
};

console.log(myArray.slice(0, findMaxIndex(myArray)));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...