Estoy tratando de seleccionar un grupo de botones de opción en una página. Cada una de las entradas tiene lo siguiente:
<input type="radio" class="wc-pao-addon-field wc-pao-addon-radio" name="addon-761-soapbar-covers-0[]" data-raw-price="32" data-price="32" data-price-type="quantity_based" value="gold-soapbar-set" data-label="Gold Soapbar (Set)"> No puedo seleccionar por los atributos de datos ya que se comparten con otras entradas que no quiero deshabilitar. Hasta ahora, solo puedo obtener el value a medida que el valor cambia de gold a níquel en raw-nickel polished-nickel a chrome , etc.
Lo que tengo es lo siguiente:
//Initialize empty array this.metalCovers = []; //Grab all inputs this.covers = Array.from(this.soapbarCovers.querySelectorAll("input")); //Then filter them by their values and store in new variable this.chromeCovers = this.covers.filter((cover) => cover.value.indexOf("chrome") !== -1); this.blackCovers = this.covers.filter((cover) => cover.value.indexOf("matte") !== -1); this.goldCovers = this.covers.filter((cover) => cover.value.indexOf("gold") !== -1); this.nickelCovers = this.covers.filter((cover) => cover.value.indexOf("nickel") !== -1); //Create new array from filtered inputs this.metalCovers = [this.chromeCovers, this.blackCovers, this.goldCovers, this.nickelCovers]; //flatten the new array this.metalCovers = [].concat.apply([], this.metalCovers); Entonces, esto funciona, pero estoy tratando de descubrir una forma más limpia de abordar este código. Estaba pensando que lo limpiaría si pudiera Array.filter() por múltiples valores, pero no surgió nada en mi investigación.
¿Te llama la atención algo?
simplemente haría algo como
// Define the keywords we're looking for in the value const keywords = ["chrome", "matte", "gold", "nickel"]; // Grab all inputs const inputs = Array.from(this.soapbarCovers.querySelectorAll("input")); // Filter them... this.metalCovers = inputs.filter((cover) => // If any of the keywords appears in the value, // this is an input we care about keywords.some((kw) => cover.value.includes(kw)) );O si quiere ser realmente eficiente y que el motor CSS del navegador haga todo el trabajo,
this.metalCovers = Array.from(this.soapbarCovers.querySelectorAll("input[value*=chrome],input[value*=matte],input[value*=gold],input[value*=nickel]"));que, por supuesto, se puede hacer más fácil de mantener a través de
const keywords = ["chrome", "matte", "gold", "nickel"]; this.metalCovers = Array.from(this.soapbarCovers.querySelectorAll(keywords.map(k => `input[value*=${k}`]).join(','));//Initialize empty array this.metalCovers = []; //Grab all inputs this.covers = Array.from(this.soapbarCovers.querySelectorAll("input")); //Then filter them by their values and store in new variable this.chromeCovers = []; this.blackCovers = []; this.goldCovers = []; this.nickelCovers = []; this.covers.forEach( cover => { switch (cover.value) { case "chrome": this.chromeCovers.push(cover); break; case "matte": this.blackCovers.push(cover); break; case "gold": this.goldCovers.push(cover); break; case "raw-nickel": case "polished-nickel": this.nickelCovers.push(cover); break; default: console.error(`Invalid cover "${cover.value}"!`); } }); //Create new array from filtered inputs this.metalCovers = [this.chromeCovers, this.blackCovers, this.goldCovers, this.nickelCovers]; //flatten the new array this.metalCovers = [].concat.apply([], this.metalCovers);Me encuentro con este:
const filtered = Array.from(this.soapbarCovers.querySelectorAll("input")) .filter(input => ['chrome', 'matte', 'gold', 'nickel'].includes(input.value));Hace más o menos lo que necesita en una sola línea.
Ejemplo:
const metalCovers = [ { attr: 'a1', value: 'chrome'}, { attr: 'a2', value: 'matte'}, { attr: 'a3', value: 'gold'}, { attr: 'a4', value: 'nickel'}, { attr: 'a5', value: 'chrome'}, { attr: 'a6', value: 'silver'}, // should be left out { attr: 'a7', value: 'copper'}, // should be left out { attr: 'a8', value: 'gold'}, { attr: 'a9', value: 'chrome'}, { attr: 'a10', value: 'matte'}, { attr: 'a11', value: 'nickel'}, ]; const filtered = metalCovers.filter(input => ['chrome', 'matte', 'gold', 'nickel'].includes(input.value)); console.log(filtered);saldrá esto:
[ { attr: 'a1', value: 'chrome' }, { attr: 'a2', value: 'matte' }, { attr: 'a3', value: 'gold' }, { attr: 'a4', value: 'nickel' }, { attr: 'a5', value: 'chrome' }, { attr: 'a8', value: 'gold' }, { attr: 'a9', value: 'chrome' }, { attr: 'a10', value: 'matte' }, { attr: 'a11', value: 'nickel' } ]