2
votes

Renvoie les valeurs d'un tableau qui sont au moins 3 fois dans le tableau

J'ai du mal à le faire, alors je le pose ici. J'ai un tableau comme celui-ci:

var filteredArray = ["hi", "hu"]

Ce que je veux, c'est stocker les valeurs qui se produisent au moins 3 fois dans un nouveau tableau. Je devrais donc obtenir:

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"]

Est-ce que quelqu'un sait comment faire cela?


3 commentaires

"Ce que je veux, c'est stocker les valeurs" ce n'est pas trier son filtrage


Voulez-vous un seul élément de trois ou plus ou tous les éléments qui comptent trois ou plus?


@NinaScholz Élément unique dans un nouveau tableau des éléments qui se produisent 3 fois dans le premier tableau.


6 Réponses :


3
votes

Vous pouvez le faire en suivant les étapes suivantes:

  • Créez une fonction qui prend un tableau et le moins de fois que l'élément doit se répéter comme argument.
  • Supprimez les doublons du tableau en utilisant Set
  • Ensuite, utilisez filter () là-dessus. À l'intérieur de filter () , utilisez filter () sur le tableau d'origine (avec des valeurs en double) pour obtenir le tableau des mêmes valeurs.
  • Comparez la longueur de ce tableau avec le nombre (deuxième paramètre)

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"];

const valWhichRepeat = (arr,count) => 
  arr.reduce(([obj,res],a) => {
    obj[a] = obj[a] + 1 || 1;
    if(obj[a] === count) res.push(a);
    return [obj,res]
  },[{},[]])[1]

console.log(valWhichRepeat(myArray,3))

Le code ci-dessus n'a pas de complexité temporelle linéaire. Si vous voulez une complexité temporelle de la ligne, vous pouvez utiliser reduction () pour construire un objet avec le nombre d'éléments, puis utiliser filter () sur ses clés.

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"];

const valWhichRepeat = (arr,count) => {
  const obj = arr.reduce((ac,a) => (ac[a] = ac[a] + 1 || 1,ac),{});
  return Object.keys(obj).filter(x => obj[x] >= count);
}
console.log(valWhichRepeat(myArray,3))

Ce qui précède utilise toujours deux boucles. Si vous ne souhaitez utiliser qu'une seule boucle, vous pouvez pousser () les éléments à l'intérieur de reduce()

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"];

const valWhichRepeat = (arr,count) => 
                 [...new Set(arr)].filter(x => 
                      arr.filter(a => a === x).length >= count 
                 );

console.log(valWhichRepeat(myArray,3))


2 commentaires

Vous pouvez voter pour :) et vous pouvez également marquer cette réponse comme bonne réponse, soit un total de 25 points de repo @Maheer Ali


@NinaScholz C'est vrai mais la complexité temporelle sera toujours dite linéaire je suppose. J'ai ajouté une méthode utilisant une boucle unique. Cependant votre solution est meilleure et VALZ encore plus meilleure.



5
votes

Vous pouvez prendre une table de hachage et compter les occurrences. Filtrez ensuite si le nombre est égal à trois.

Cette approche fonctionne avec une seule boucle: O(n) final

var array = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"],
    hash = {},
    result = array.filter(v => (hash[v] = (hash[v] || 0) + 1) === 3);

console.log(result);


0 commentaires

2
votes
Object.entries(myArray.reduce((res, cur) => {
    res[cur] = (res[cur] || 0) + 1
    return res
}, {})).filter(([k, v]) => v >= 3).map(([k, v]) => k)

3 commentaires

Pourriez-vous commenter un peu votre réponse?


Après avoir réduit, retournez une carte (clé: chaîne dans myArray, valeur: le nombre total) Object.entries itérera la carte et retournera un tableau. Et le filtre trouvera le filtre à la valeur correcte. Et la carte renverra la structure de données dont vous avez besoin.


Je suppose que ça devrait être (res [cur] || 0) + 1



7
votes

Vous pouvez faire un .filter sans avoir besoin de variables supplémentaires en utilisant le second paramètre optionnel qui assigne le this contexte du callback. Vous pouvez donc en tirer parti pour garder un compte de tout ce que vous avez rencontré et autoriser uniquement les éléments avec un nombre de 3.

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"]

var filteredArray = myArray.filter(item => (this[item] = ++this[item] || 1) === 3, {})
 
console.log(filteredArray)

Pour une implémentation plus concise, vous pouvez utiliser celle suggérée par @georg

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"]

var filteredArray = myArray.filter(item => {
  //check what the count so far is
  var count = this[item] ? this[item] : 0;
  //add one and assign it back as the new count
  this[item] = ++count;
  
  //only return the item if the count is 3
  return count === 3;
 }, {})
 
console.log(filteredArray)


3 commentaires

Bonne idée, vous pouvez également jouer au golf sur la fonction (this [item] = ++ this [item] || 1) === 3


@georg Je cherchais à la clarté, mais vous avez raison. J'ai commencé par quelque chose de similaire, mais j'ai ensuite développé :)


J'aime plus la version lisible, vous savez pourquoi quand vous avez besoin de travailler avec d'autres.



1
votes

var myArray = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"]
var temp = {}
var filteredArray = []
for(let i = 0;i < myArray.length;i++){
    if(temp[myArray[i]]){
        temp[myArray[i]] += 1
    }else{
        temp[myArray[i]] = 1
    }
}
for(let key in temp){
    if(temp[key] >= 3){
        filteredArray.push(key)
    }
}

console.log(filteredArray);


0 commentaires

1
votes

function count() {
    array_elements = ["hi", "hi", "hi", "ha", "ha", "ho", "hu", "hu", "hu"];
    var filteredArray = [];
    var current = null;
    var cnt = 0;
    for (var i = 0; i < array_elements.length; i++) {
        if (array_elements[i] != current) {
            if (cnt >= 3) {
            		filteredArray.push(current);
            }
            current = array_elements[i];
            cnt = 1;
        } else {
            cnt++;
        }
    }
    if (cnt >= 3) {
      filteredArray.push(current);
    }
  document.write(filteredArray);
}
count()


1 commentaires

Cela se traduit par hi uniquement