Gunnar Bittersmann: URLSearchParams filtern

Hi, ich möchte aus URLSearchParams nur diejenigen Einträge haben, deren Keys mit einem bestimmten Präfix beginnen.

const url = "https://example.net?a=1&b=2&c=3&pre_d=4&pre_e=5";

const urlObject = new URL(url);
const searchParams = urlObject.searchParams;

searchParams.forEach((value, key) => {
	console.debug("key", key);
	if (!key.startsWith("pre_")) {
		searchParams.delete(key);
	}
});

console.debug("result", searchParams.toString());

// console output:
// "key" "a"
// "key" "c"
// "key" "pre_e"
// "result" "b=2&pre_d=4&pre_e=5"

(Codepen)

In der Schleife werden gar nicht alle Keys geprüft; b und pre_d fehlen.

Warum ist das so und was muss ich dagegen tun?

Jolan tru

--
Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)

akzeptierte Antworten

  1. Hallo,

    weil du mit forEach immer direkt am Object arbeitest. Ich habe es mir inzwischen abgewöhnt, mit forEach zu arbeiten, da man schnell den Überblick verliert, ob und wie es die nachfolgende Iteration beeinflusst.

    Um sicherzustellen, dass alle keys durchlaufen werden, erstelle vorher ein Array mit den keys. Zum Beispiel:

    const url = 'https://example.net?a=1&b=2&c=3&pre_d=4&pre_e=5';
    
    const urlObject = new URL(url);
    const searchParams = urlObject.searchParams;
    
    [...searchParams].map(([key,]) => {
    	console.debug('key', key);
      if (!key.startsWith('pre_')) {
    		searchParams.delete(key);
    	}
    });
    
    console.debug('result', searchParams.toString());
    

    Gruß Michael

    1. Hallo Michael_K,

      ja, das dachte ich mir auch. Never Modify A Collection White Iterating It!

      Da die searchParams key/value-iterierbar sind, könnte man als generische Lösung einen Generator erstellen und ihn als Quelle für eine Map verwenden:

      function *selectPrefix(keyValueIterable, prefix) {
          for (const entry of keyValueIterable) {
              if (entry[0].startsWith(prefix)) {
                  yield entry;
              }
          }
      }
      
      const relevantParams = new Map(
         selectPrefix(url.searchParams, "pre_")
      );
      

      Aber sicherlich war das nur das Programmierquiz zum Wochenende, oder Gunnar? 😉

      Rolf

      --
      sumpsi - posui - obstruxi
      1. @@Rolf B

        Da die searchParams key/value-iterierbar sind, könnte man als generische Lösung einen Generator erstellen und ihn als Quelle für eine Map verwenden:

        Wenn ich das noch öfter brauchen sollte, werde ich drauf zurückkommen.

        Aber sicherlich war das nur das Programmierquiz zum Wochenende, oder Gunnar? 😉

        Leider nicht.

        Jolan tru

        --
        Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
    2. @@Michael_K

      weil du mit forEach immer direkt am Object arbeitest. Ich habe es mir inzwischen abgewöhnt, mit forEach zu arbeiten, da man schnell den Überblick verliert, ob und wie es die nachfolgende Iteration beeinflusst.

      Ja, sowas dachte ich mir schon.

      Um sicherzustellen, dass alle keys durchlaufen werden, erstelle vorher ein Array mit den keys. Zum Beispiel:

      Danke, das funzt.

      Jolan tru

      --
      Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)