Tengo 2 etiquetas de matrices y nombres de tipos:
const tags = [ { title: 'Warrior', data: { type: 'audience' } }, { title: 'Juggler', data: { type: 'section' } }, { title: 'Journey', data: { type: 'audience' } }, { title: 'Travel', data: { type: 'nonexistingtag' } } ]; const typenames = [ { audience: 'au' }, { section: 'se' }, { sponsor: 'sp' }, { contextual: 'co' } ]El resultado esperado es crear una cadena que se agrupa por claves que coinciden entre el tipo array1 y array2 y cada clave está separada por la tubería "|" símbolo y cada grupo está separado por "&" entre sí, por lo que para la muestra anterior, la cadena de salida final esperada sería:
au=Warrior|au=Journey&se=JugglerEsto es lo que probé hasta ahora,
let arr = []; tags.forEach(element => { typenames.forEach(el => { if (Object.keys(el)[0] === element.data.type) // finding matching keys and pushing to an arr arr.push({ title: Object.values(el)[0], desc: element.title }); }) });Ordene las claves para que sean fáciles de agrupar:
arr.sort((a, b) => { let keya = a.title; let keyb = b.title; if (keya > keyb) { return 1; } else if (keya < keyb) { return -1; } else { // the characters are equal. return 0; } });Concatenar la cadena:
let str = ''; arr.forEach(({ title, desc }, i, arr2) => { if (title === arr2[i + 1]?.title) { // Check that the next item in array has the same title str = str.concat(`${title}=${desc}|`) return; } str = str.concat(`&${title}=${desc}`) }); console.log('str', str); Salida: au=Warrior|&au=Journey&se=Juggler
Problemas :
Teniendo en cuenta el problema, en última instancia, desea iterar a través de todos los nombres de tipos y ver qué valores coinciden en las etiquetas, por lo que debe comenzar reestructurando la matriz de etiquetas para que sea más fácil de buscar, en lugar de tratar de recorrer todo el algo intrincado. estructura cada vez. Tal vez un objeto indexado por el tipo, por ejemplo:
{ audience: ['Warrior', 'Journey'], section: ['Juggler'], nonexistingtag: ['nonexistingtag'] }Luego, al revisar los nombres de tipos, todo lo que necesita hacer es buscar la propiedad vinculada en el objeto y unir dos veces:
['Warrior', 'Journey'] a au=Warrior|au=JourneyEs mucho más fácil usar estructuras de datos agrupados como matrices que puede unir en lugar de agregar un separador en función de si el siguiente elemento de la matriz tiene una determinada propiedad.
const tags=[{title:"Warrior",data:{type:"audience"}},{title:"Juggler",data:{type:"section"}},{title:"Journey",data:{type:"audience"}},{title:"Travel",data:{type:"nonexistingtag"}}],typenames=[{audience:"au"},{section:"se"},{sponsor:"sp"},{contextual:"co"}]; const titlesByType = {}; for (const { title, data: { type } } of tags) { titlesByType[type] ??= []; titlesByType[type].push(title); } const combinedStrs = []; for (const typeObj of typenames) { const [[key, abbrev]] = Object.entries(typeObj); if (titlesByType[key]) { combinedStrs.push(titlesByType[key].map(str => `${abbrev}=${str}`).join('|')); } } const output = combinedStrs.join('&'); console.log(output);Este es un truco estándar para obtener inteligentemente "pegamento" correcto al ensamblar cuerdas.
Array.prototype.join para producir la cadena finalEstoy pensando en algo como esto:
let items = arr.reduce((output, { title, desc }, i, fullArray) => { if (title === fullArray[i + 1]?.title) { output.push(`${title}=${desc}|`) } return output }, []) let str = items.join('&')Puedes probar este método simple y legible:
const availableTags = [ { title: 'Warrior', data: { type: 'audience' } }, { title: 'Juggler', data: { type: 'section' } }, { title: 'Journey', data: { type: 'audience' } }, { title: 'Travel', data: { type: 'nonexistingtag' } } ]; const availableTypenames = [ { audience: 'au' }, { section: 'se' }, { sponsor: 'sp' }, { contextual: 'co' } ]; const getResultString = (tags, typenames) => { let result = ''; for (const typename of typenames) { const type = Object.keys(typename)[0]; let needSeparate = false; for (const tag of tags) { if (type === tag.data.type) { result +=`${needSeparate ? '|' : '&'}${typename[type]}=${tag.title}`; needSeparate = true; } } } return result.slice(1); } console.log(getResultString(availableTags, availableTypenames))