最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - how to shorten this JS function - Stack Overflow

programmeradmin3浏览0评论

I have this Js function with hard coded filter parameters. It filter all the buckets sub objects when key start with a string from a given list. For now i havent found a way to put this list as an array...

     function filter(buckets) {
      return buckets.filter(({key}) => {
        const _key = key.toLowerCase();
        return (
          !_key.startsWith("anciennes") && !_key.startsWith("anciens") && !_key.startsWith("arrondissements") && !_key.startsWith("autorites") && !_key.startsWith("cantons") && !_key.startsWith("capitales") &&
          !_key.startsWith("chaines") && !_key.startsWith("chefs lieux") && !_key.startsWith("circonscriptions") && !_key.startsWith("munautes d") && !_key.startsWith("tes d") && !_key.startsWith("constellations") && !_key.startsWith("continents") &&
          !_key.startsWith("cours d") && !_key.startsWith("départements") && !_key.startsWith("districts d") && !_key.startsWith("établissements") && !_key.startsWith("états") && !_key.startsWith("ethnonymes") && !_key.startsWith("étoiles") &&
          !_key.startsWith("europe") && !_key.startsWith("îles") && !_key.startsWith("lander-allemands") && !_key.startsWith("lieux-mythologiques") && !_key.startsWith("Localités d") && !_key.startsWith("mers") &&
          !_key.startsWith("montagnes") && !_key.startsWith("municipalité") && !_key.startsWith("fromage") && !_key.startsWith("localités") && !_key.startsWith("noms de") && !_key.startsWith("numéros de") &&
          !_key.startsWith("odonymes") && !_key.startsWith("organisations internationales") && !_key.startsWith("pays ") && !_key.startsWith("péninsules") && !_key.startsWith("préfectures") && !_key.startsWith("provinces") && !_key.startsWith("quartiers") &&
          !_key.startsWith("régions") && !_key.startsWith("réserves indiennes") && !_key.startsWith("sous ") && !_key.startsWith("territoires") && !_key.startsWith("toponymes ") && !_key.startsWith("unions supranationales") && !_key.startsWith("villes du quebec") && !_key.startsWith("voivodies de pologne")
        )
      })
    }


    const buckets = [
      {"key": "Aliments", "doc_count": 10}, {"key": "Adjectifs", "doc_count": 7}, {"key": "Vêtements", "doc_count": 6}, {"key": "Armures", "doc_count": 5}, {"key": "Anciennes divisions géographiques", "doc_count": 4}, {"key": "Super-règnes", "doc_count": 4},
      {"key": "Eucaryotes", "doc_count": 3}, {"key": "Pays", "doc_count": 3}, {"key": "Antonomases", "doc_count": 2}, {"key": "Continents", "doc_count": 2}, {"key": "Europe", "doc_count": 2}, {"key": "France", "doc_count": 2},
      {"key": "Localités", "doc_count": 2}, {"key": "Localités de France", "doc_count": 2}, {"key": "Plantes", "doc_count": 2}, {"key": "États", "doc_count": 2}, {"key": "Acaryotes", "doc_count": 1},
      {"key": "Animaux", "doc_count": 1}, {"key": "Armes", "doc_count": 1}, {"key": "Aromates", "doc_count": 1}, {"key": "Chordés", "doc_count": 1}, {"key": "Couleurs", "doc_count": 1}, {"key": "Créatures mythologiques", "doc_count": 1},
      {"key": "Fromages", "doc_count": 1}, {"key": "Fromages forts", "doc_count": 1}, {"key": "Fromages à pâte filée", "doc_count": 1}, {"key": "Fruits", "doc_count": 1}, {"key": "Langages informatiques", "doc_count": 1},
      {"key": "Localités du département de la Corrèze", "doc_count": 1}, {"key": "Localités du département de la Dordogne", "doc_count": 1}, {"key": "Machines", "doc_count": 1}, {"key": "Oiseaux", "doc_count": 1}, {"key": "Tétrapodes", "doc_count": 1},
      {"key": "Vertébrés", "doc_count": 1}, {"key": "Vie domestique", "doc_count": 1}, {"key": "Virus", "doc_count": 1}, {"key": "Volcans", "doc_count": 1}
    ];

jsbin here :

,console

how to transform this function to generate the !_key.startsWith( ... ) && from and array of string insted of this crazy hard coded long &&

      const listOfTermToIgnore =  ["anciennes", "anciens", "arrondissements", "autorites", "cantons", "capitales",
          "chaines", "chefs lieux", "circonscriptions", "munautes d", "tes d", "constellations", "continents",
          "cours d", "départements", "districts d", "établissements", "états", "ethnonymes", "étoiles",
          "europe", "îles", "lander-allemands", "lieux-mythologiques", "Localités d", "mers",
          "montagnes", "municipalité", "fromage", "localités", "noms de", "numéros de",
          "odonymes", "organisations internationales", "pays ", "péninsules", "préfectures", "provinces", "quartiers",
          "régions", "réserves indiennes", "sous ", "territoires", "toponymes ", "unions supranationales", "villes du quebec", "voivodies de pologne" ]

thanks for reading

I have this Js function with hard coded filter parameters. It filter all the buckets sub objects when key start with a string from a given list. For now i havent found a way to put this list as an array...

     function filter(buckets) {
      return buckets.filter(({key}) => {
        const _key = key.toLowerCase();
        return (
          !_key.startsWith("anciennes") && !_key.startsWith("anciens") && !_key.startsWith("arrondissements") && !_key.startsWith("autorites") && !_key.startsWith("cantons") && !_key.startsWith("capitales") &&
          !_key.startsWith("chaines") && !_key.startsWith("chefs lieux") && !_key.startsWith("circonscriptions") && !_key.startsWith("munautes d") && !_key.startsWith("tes d") && !_key.startsWith("constellations") && !_key.startsWith("continents") &&
          !_key.startsWith("cours d") && !_key.startsWith("départements") && !_key.startsWith("districts d") && !_key.startsWith("établissements") && !_key.startsWith("états") && !_key.startsWith("ethnonymes") && !_key.startsWith("étoiles") &&
          !_key.startsWith("europe") && !_key.startsWith("îles") && !_key.startsWith("lander-allemands") && !_key.startsWith("lieux-mythologiques") && !_key.startsWith("Localités d") && !_key.startsWith("mers") &&
          !_key.startsWith("montagnes") && !_key.startsWith("municipalité") && !_key.startsWith("fromage") && !_key.startsWith("localités") && !_key.startsWith("noms de") && !_key.startsWith("numéros de") &&
          !_key.startsWith("odonymes") && !_key.startsWith("organisations internationales") && !_key.startsWith("pays ") && !_key.startsWith("péninsules") && !_key.startsWith("préfectures") && !_key.startsWith("provinces") && !_key.startsWith("quartiers") &&
          !_key.startsWith("régions") && !_key.startsWith("réserves indiennes") && !_key.startsWith("sous ") && !_key.startsWith("territoires") && !_key.startsWith("toponymes ") && !_key.startsWith("unions supranationales") && !_key.startsWith("villes du quebec") && !_key.startsWith("voivodies de pologne")
        )
      })
    }


    const buckets = [
      {"key": "Aliments", "doc_count": 10}, {"key": "Adjectifs", "doc_count": 7}, {"key": "Vêtements", "doc_count": 6}, {"key": "Armures", "doc_count": 5}, {"key": "Anciennes divisions géographiques", "doc_count": 4}, {"key": "Super-règnes", "doc_count": 4},
      {"key": "Eucaryotes", "doc_count": 3}, {"key": "Pays", "doc_count": 3}, {"key": "Antonomases", "doc_count": 2}, {"key": "Continents", "doc_count": 2}, {"key": "Europe", "doc_count": 2}, {"key": "France", "doc_count": 2},
      {"key": "Localités", "doc_count": 2}, {"key": "Localités de France", "doc_count": 2}, {"key": "Plantes", "doc_count": 2}, {"key": "États", "doc_count": 2}, {"key": "Acaryotes", "doc_count": 1},
      {"key": "Animaux", "doc_count": 1}, {"key": "Armes", "doc_count": 1}, {"key": "Aromates", "doc_count": 1}, {"key": "Chordés", "doc_count": 1}, {"key": "Couleurs", "doc_count": 1}, {"key": "Créatures mythologiques", "doc_count": 1},
      {"key": "Fromages", "doc_count": 1}, {"key": "Fromages forts", "doc_count": 1}, {"key": "Fromages à pâte filée", "doc_count": 1}, {"key": "Fruits", "doc_count": 1}, {"key": "Langages informatiques", "doc_count": 1},
      {"key": "Localités du département de la Corrèze", "doc_count": 1}, {"key": "Localités du département de la Dordogne", "doc_count": 1}, {"key": "Machines", "doc_count": 1}, {"key": "Oiseaux", "doc_count": 1}, {"key": "Tétrapodes", "doc_count": 1},
      {"key": "Vertébrés", "doc_count": 1}, {"key": "Vie domestique", "doc_count": 1}, {"key": "Virus", "doc_count": 1}, {"key": "Volcans", "doc_count": 1}
    ];

jsbin here :

https://jsbin./xicejozafe/edit?js,console

how to transform this function to generate the !_key.startsWith( ... ) && from and array of string insted of this crazy hard coded long &&

      const listOfTermToIgnore =  ["anciennes", "anciens", "arrondissements", "autorites", "cantons", "capitales",
          "chaines", "chefs lieux", "circonscriptions", "munautes d", "tes d", "constellations", "continents",
          "cours d", "départements", "districts d", "établissements", "états", "ethnonymes", "étoiles",
          "europe", "îles", "lander-allemands", "lieux-mythologiques", "Localités d", "mers",
          "montagnes", "municipalité", "fromage", "localités", "noms de", "numéros de",
          "odonymes", "organisations internationales", "pays ", "péninsules", "préfectures", "provinces", "quartiers",
          "régions", "réserves indiennes", "sous ", "territoires", "toponymes ", "unions supranationales", "villes du quebec", "voivodies de pologne" ]

thanks for reading

Share Improve this question asked Jan 25, 2022 at 16:51 AlainIbAlainIb 4,7285 gold badges41 silver badges67 bronze badges 4
  • Array .reduce may help here, I think. Let me try an answer. – jsN00b Commented Jan 25, 2022 at 16:53
  • 1 Localités d should be localités d – ikegami Commented Jan 25, 2022 at 17:12
  • localités d is redundant with localités – ikegami Commented Jan 25, 2022 at 17:14
  • yes i made a typo here thanks ! . – AlainIb Commented Jan 25, 2022 at 17:22
Add a ment  | 

5 Answers 5

Reset to default 8

You can use the inverse of array.some. It will return false if _key starts with any item from the array, or true otherwise.

 function filter(buckets) {
  return buckets.filter(({key}) => {
    const _key = key.toLowerCase();
    return !listOfTermToIgnore.some(item => _key.startsWith(item))
  })
}

Use array.every() to check all the elements of the array.

function filter(buckets) {
    return buckets.filter(({key}) => {
        const _key = key.toLowerCase();
        return listOfTtermToIgnore.every(term => !_key.startsWith(term))
    }
});

For the one-time cost of creating a regex, you get the following high performance solution:

function quotemeta(s) {
   return String(s).replace(/\W/g, "\\$&");
}

const listOfTermToIgnore = [
   "anciennes", "anciens", "arrondissements", "autorites", "cantons",
   "capitales", "chaines", "chefs lieux", "circonscriptions",
   "munautes d", "tes d", "constellations", "continents",
   "cours d", "départements", "districts d", "établissements",
   "états", "ethnonymes", "étoiles", "europe", "îles",
   "lander-allemands", "lieux-mythologiques", "mers", "montagnes",
   "municipalité", "fromage", "localités", "noms de", "numéros de",
   "odonymes", "organisations internationales", "pays ", "péninsules",
   "préfectures", "provinces", "quartiers", "régions", "réserves indiennes",
   "sous ", "territoires", "toponymes ", "unions supranationales",
   "villes du quebec", "voivodies de pologne"
];

const filter_re = new RegExp(
   "^(?:" + listOfTermToIgnore.map( _ => quotemeta(_) ).join("|") + ")"
);

function filter(buckets) {
    return buckets.filter( _ => !filter_re.test( _.toLowerCase() ) );
}

console.log( filter( [ "anciennes", "xanciennes", "anciennesx", "banane" ] ) );

It's mon to use this approach in Perl, but Perl optimizes this kind of alternation into a trie, which is extremely fast. It just occurred to me that your favourite JavaScript might not do that, so it might not be as performant as I thought earlier. Still, moving the checking of all these strings to the regex engine should still be faster than checking them all in JavaScript code.

But if you had a truly long list of terms to ignore, I'd remend using a trie.

A bit of an old-school way may be something like below:

const myBucketsFilter = (arr = buckets, ignoreList = listOfTermToIgnore) => (
    arr.filter(o => ignoreList.reduce(
    (acc, itm) => (acc && !o.key.toLowerCase().startsWith(itm)), true)
  )
);

Explanation

  • use .filter to filter through buckets array
  • for each bucket-item o, use .reduce to return true or false based on o.key starting with any of the elements of ignoreList

Code Snippet

const listOfTermToIgnore =  ["anciennes", "anciens", "arrondissements", "autorites", "cantons", "capitales", "chaines", "chefs lieux", "circonscriptions", "munautes d", "tes d", "constellations", "continents", "cours d", "départements", "districts d", "établissements", "états", "ethnonymes", "étoiles", "europe", "îles", "lander-allemands", "lieux-mythologiques", "Localités d", "mers", "montagnes", "municipalité", "fromage", "localités", "noms de", "numéros de", "odonymes", "organisations internationales", "pays ", "péninsules", "préfectures", "provinces", "quartiers", "régions", "réserves indiennes", "sous ", "territoires", "toponymes ", "unions supranationales", "villes du quebec", "voivodies de pologne" ];

const buckets = [ {"key": "anciennes", "doc_count": 0}, {"key": "Aliments", "doc_count": 10}, {"key": "Adjectifs", "doc_count": 7}, {"key": "Vêtements", "doc_count": 6}, {"key": "Armures", "doc_count": 5}, {"key": "Anciennes divisions géographiques", "doc_count": 4}, {"key": "Super-règnes", "doc_count": 4}, {"key": "Eucaryotes", "doc_count": 3}, {"key": "Pays", "doc_count": 3}, {"key": "Antonomases", "doc_count": 2}, {"key": "Continents", "doc_count": 2}, {"key": "Europe", "doc_count": 2}, {"key": "France", "doc_count": 2}, {"key": "Localités", "doc_count": 2}, {"key": "Localités de France", "doc_count": 2}, {"key": "Plantes", "doc_count": 2}, {"key": "États", "doc_count": 2}, {"key": "Acaryotes", "doc_count": 1}, {"key": "Animaux", "doc_count": 1}, {"key": "Armes", "doc_count": 1}, {"key": "Aromates", "doc_count": 1}, {"key": "Chordés", "doc_count": 1}, {"key": "Couleurs", "doc_count": 1}, {"key": "Créatures mythologiques", "doc_count": 1}, {"key": "Fromages", "doc_count": 1}, {"key": "Fromages forts", "doc_count": 1}, {"key": "Fromages à pâte filée", "doc_count": 1}, {"key": "Fruits", "doc_count": 1}, {"key": "Langages informatiques", "doc_count": 1}, {"key": "Localités du département de la Corrèze", "doc_count": 1}, {"key": "Localités du département de la Dordogne", "doc_count": 1}, {"key": "Machines", "doc_count": 1}, {"key": "Oiseaux", "doc_count": 1}, {"key": "Tétrapodes", "doc_count": 1}, {"key": "Vertébrés", "doc_count": 1}, {"key": "Vie domestique", "doc_count": 1}, {"key": "Virus", "doc_count": 1}, {"key": "Volcans", "doc_count": 1}];

const myBucketsFilter = (arr = buckets, ignoreList = listOfTermToIgnore) => (
    arr.filter(o => ignoreList.reduce(
    (acc, itm) => (acc && !o.key.toLowerCase().startsWith(itm)), true)
  )
);

console.log('with default params: ', myBucketsFilter());
console.log('check if custom key anciennes was filtered-in: ', myBucketsFilter().includes("anciennes"));

What you could use is create an array of IGNORING keys. Then in your filter function just use the negative some statement for know what pass and pass not.

 const filter = buckets => {
    //Create a array of keys that you want to ignore
    const ignoreList = [
        "anciennes",
        "anciens",
        "arrondissements",
    ]
    return buckets.filter(({ key }) => {
        return !ignoreList.some(item => key.toLowerCase().startsWith(item))
    })
}
发布评论

评论列表(0)

  1. 暂无评论