2
votes

Diviser un tableau de nombres en groupes triés

J'ai un tableau avec des nombres dont la valeur absolue est garantie inférieure à 10.

Ce que je fais maintenant, c'est le trier par ordre croissant en utilisant Array.prototype.sort () :

myArray.sort(function (a, b) {
    if(a === b){
        this.myArray.push(b);
        return 0;
    }
    else{
        return a - b;
    }
})

Mais la tâche est de trier par groupes sans répétitions, c'est-à-dire avoir un tableau

a = [1,2, 2,3,1,4,4,2,9,8]

J'ai besoin d'obtenir la sortie

b = [1,2, 3,4,8,9,1,2,4]

J'ai eu l'idée d'utiliser Array.prototype.push () à l'intérieur d'une expression fonctionnelle à ajouter numéros en double à la fin du tableau. Mais pour des raisons évidentes, je ne peux pas le faire en raison de l'existence d'une portée:

myArray.sort(function (a, b) {
    return a - b;
})

Est-il possible de mettre en œuvre mon idée en utilisant Array.prototype.sort ( ) ou est-il plus facile et plus correct d'écrire une fonction séparée?


2 commentaires

@MarkMeyer Autre exemple: a = [1,1,2,2,3,3,4,4,5,5] Résultat souhaitable: b = [1,2,3, 4,5,1,2,3,4,5]


Désolé @Nikita - J'ai mal lu la question et je n'ai pas vu l'exemple que vous avez publié.


3 Réponses :


3
votes

Vous pouvez utiliser trier avec map en utilisant un objet temporaire avec une table de hachage pour le même tableau de groupe. Prenez-en la longueur du tableau utilisé comme groupe pour le tri.

Le tri se produit avec le groupe et la valeur.

Le résultat est mappé avec l'index du tableau temporaire trié.

var array = [1,2,2,3,1,4,4,2,9,8],
    groups = Object.create(null),
    result = array
        .map((value, index) => ({ index, value, group: groups[value] = (groups[value] || 0 ) + 1 }))
        .sort((a, b) => a.group - b.group || a.value - b.value)
        .map(({ value }) => value);

console.log(...result);


2 commentaires

Pourquoi pas groups [value] = (groups [value] || 0) + 1 ? Et pourquoi pas .map (({value}) => value) ?


Aussi || a.index - b.index est superflouos (tant que personne ne travaille avec des objets Number)



1
votes

Vous pouvez créer un objet group qui crée chaque nombre comme clé et un tableau du nombre comme valeur. Ensuite, parcourez l'objet et ajoutez chaque nombre à la sortie. Chaque fois que le tableau devient vide, supprimez la clé. Exécutez ceci jusqu'à ce que l'objet n'ait plus de clé.

const input = [1, 2, 2, 3, 1, 4, 4, 2, 9, 8],
      group = {},
      output = [];

input.forEach(n => (group[n] = group[n] || []).push(n))

while (Object.keys(group).length > 0) {
  for (const key in group) {
    output.push(group[key].pop())

    if (group[key].length === 0)
      delete group[key];
  }
}

console.log(output)

( Remarque : pour les clés numériques, les clés d'un objet sont parcourues dans l'ordre croissant. Donc, cela ne fonctionne que s'il y a des nombres naturels dans le tableau) p >


0 commentaires

1
votes

Vous trouverez ci-dessous une approche à adopter - les commentaires expliquent en détail à quoi sert chaque étape:

const a = [1, 2, 2, 3, 1, 4, 4, 2, 9, 8];

//Create an occurrence map
const map = a.reduce((accum, i) => {
  if (accum[i]) {
    accum[i] += 1;
  } else {
    accum[i] = 1;
  }

  return accum;
}, {});

//We need to iterate the map as many times as the largest value
const iterations = Math.max(...Object.values(map));

const sorted = [];
for (let i = 0; i < iterations; i += 1) {
  Object.entries(map).forEach(entry => {
    const [val, count] = entry;
    if (count > 0) {
      sorted.push(parseInt(val)); //Add it to our sorted array
      map[val] -= 1; //Reduce the number of occurrences in the map for this key
    }
  });
}

console.log(sorted);


0 commentaires