Biorąc pod uwagę let n = 9, chcę zwrócić [6, 7, 8, 9, 10, 11, 12]. Wiem, że mogę to napisać tak:

const up = [...Array(4).keys()].map(i => i + 9)
const down = [...Array(4).keys()].map(i => 9 - i).reverse()
const result = [...new Set([...down, ...up])]

Ale jeśli n zostanie zmienione na 1, chcę zwrócić tylko pozytywy. Jak to zrobić bez kilku instrukcji if? Czy jest bardziej efektywny sposób na napisanie tego? To dla paginatora, jeśli nie możesz powiedzieć.

0
t56k 2 kwiecień 2020, 03:20

5 odpowiedzi

Najlepsza odpowiedź

Możesz użyć Array.filter(), aby odfiltrować wartości, które wykraczają poza minimalną i maksymalną liczbę stron. Włączenie funkcji dla wygody:

const paginate = function(num, pages, min, max) {
  const up = [...Array(pages - 1).keys()].map(i => num + i + 1).filter(i => i <= max);
  const down = [...Array(pages - 1).keys()].reverse().map(i => num - i - 1).filter(i => i >= min);
  return [...down, num, ...up];
}

console.log(paginate(5, 4, 1, 10));
console.log(paginate(9, 4, 1, 10));
console.log(paginate(1, 4, 1, 10));

Można to uprościć, aby:

const paginate = (num, pages, min, max) =>
  [...Array(pages * 2 - 1).keys()].map(i => num + 1 - pages + i).filter(i => i <= max && i >= min);

console.log(paginate(5, 4, 1, 10));
console.log(paginate(9, 4, 1, 10));
console.log(paginate(1, 4, 1, 10));
1
Nick 2 kwiecień 2020, 00:48

Oto potencjalne rozwiązanie, które jest nieco bardziej skonsolidowane.

const pager = (current) => [...Array(7).keys()]
  .map(el => el - 3 + current)
  .filter(el => el > 0);
  
  console.log(pager(1));
  console.log(pager(4));
  console.log(pager(8));
  console.log(pager(15));
1
Nick 2 kwiecień 2020, 00:36

Przyjąłbym inne podejście, w którym przeglądasz wartości. Nie ma potrzeby dekonstruowania tablicy.

const spread = (num, range, max=100) => {
  let ary=[];
  for (let i=num-range; i<num+range+1; i++) {
    if (i > 0 && i < max) ary.push(i);
  }
  return ary;
}

console.log(spread(9, 3));
// [6, 7, 8, 9, 10, 11, 12]

console.log(spread(1, 3));
// [1, 2, 3, 4]
1
Joseph Cho 2 kwiecień 2020, 00:38

Array.filter (który tworzy kolejną nową tablicę) nie jest konieczne. Na przykład:

function foo(n) { // n must be >= -3
  return n>3 ? [...Array(7).keys()].map(x => x + n - 3) : [...Array(3+n).keys()].map(x => x + 1)
}

console.log(foo(-3))
console.log(foo(-2))
console.log(foo(-1))
console.log(foo(0))
console.log(foo(1))
console.log(foo(2))
console.log(foo(3))
console.log(foo(4))
console.log(foo(9))
1
cybersam 2 kwiecień 2020, 01:36

Moja odpowiedź brzmi:

[...result].filter(i => i > 0)

Działa wystarczająco dobrze, chociaż do paginacji będzie to również wymagało filtrowania górnego zakresu, ale zadziała inny filtr, taki jak .filter(i => i < this.totalPages) lub cokolwiek innego.

0
okay56k 2 kwiecień 2020, 00:39