136 votes

Diviser un tableau par une fonction filtre

J'ai un tableau Javascript que je voudrais diviser en deux en fonction du retour d'une fonction appelée sur chaque élément. true o false . Il s'agit essentiellement d'un array.filter mais j'aimerais également avoir sous la main les éléments qui ont été filtrés. out .

Actuellement, mon plan est d'utiliser array.forEach et appeler la fonction prédicat sur chaque élément. Selon que cette fonction est vraie ou fausse, je vais pousser l'élément actuel sur l'un des deux nouveaux tableaux. Existe-t-il une manière plus élégante ou meilleure de procéder ? Un site array.filter où le poussera l'élément sur un autre tableau avant de retourner false par exemple ?

3voto

Andreas Gassmann Points 2584

J'ai fini par le faire parce que c'est facile à comprendre :

const partition = (array, isValid) => {
  const pass = []
  const fail = []
  array.forEach(element => {
    if (isValid(element)) {
      pass.push(element)
    } else {
      fail.push(element)
    }
  })
  return [pass, fail]
}

// usage
const [pass, fail] = partition([1, 2, 3, 4, 5], (element) => element > 3)

Et la même méthode en incluant les types pour le script :

const partition = <T>(array: T[], isValid: (element: T) => boolean): [T[], T[]] => {
  const pass: T[] = []
  const fail: T[] = []
  array.forEach(element => {
    if (isValid(element)) {
      pass.push(element)
    } else {
      fail.push(element)
    }
  })
  return [pass, fail]
}

// usage
const [pass, fail] = partition([1, 2, 3, 4, 5], (element: number) => element > 3)

0voto

Sebastian Points 38

Je sais qu'il existe déjà de multiples solutions mais j'ai pris la liberté de rassembler les meilleurs morceaux des réponses ci-dessus et d'utiliser des méthodes d'extension sur Typescript. Copier et coller et ça marche tout simplement :

declare global {

  interface Array<T> {
    partition(this: T[], predicate: (e: T) => boolean): T[][];
  }

}

if(!Array.prototype.partition){

  Array.prototype.partition = function<T>(this: T[], predicate: (e: T) => boolean): T[][] {

    return this.reduce<T[][]>(([pass, fail], elem) => {
      (predicate(elem) ? pass : fail).push(elem);
      return [pass, fail];
    }, [[], []]);

  }
}

Utilisation :

const numbers = [1, 2, 3, 4, 5, 6];
const [even, odd] = numbers.partition(n => n % 2 === 0);

0voto

nos nart Points 209

Partition Lodash alternative, identique à celle de l première solution de @Yaremenko Andrii mais avec une syntaxe plus courte

function partition(arr, callback) {
  return arr.reduce(
    (acc, val, i, arr) => {
      acc[callback(val, i, arr) ? 0 : 1].push(val)
      return acc
    },
    [[], []]
  )
}

0voto

nkitku Points 76

Partition ONE-LINER

const partitionBy = (arr, predicate) =>
    arr.reduce((acc, item) => (acc[+!predicate(item)].push(item), acc), [[], []]);

DEMO

// to make it consistent to filter pass index and array as arguments
const partitionBy = (arr, predicate) =>
    arr.reduce(
        (acc, item, index, array) => (
            acc[+!predicate(item, index, array)].push(item), acc
        ),
        [[], []]
    );

console.log(partitionBy([1, 2, 3, 4, 5], x => x % 2 === 0));
console.log(partitionBy([..."ABCD"], (x, i) => i % 2 === 0));

Pour Typescript (v4.5)

const partitionBy = <T>(
  arr: T[],
  predicate: (v: T, i: number, ar: T[]) => boolean
) =>
  arr.reduce(
    (acc, item, index, array) => {
      acc[+!predicate(item, index, array)].push(item);
      return acc;
    },
    [[], []] as [T[], T[]]
  );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X