J'ai donc ce tableau d'objets:
{props.rows && props.rows.map((row, index) => { return ( <div key={index}> <h4>{get(row, 'categories')[index].name}</h4> <ul className='link-group--list'> {row.categories.map((link, index) => { return ( <li key={index}> <a href={row.url}> {link.name} </a> </li> ); })} </ul> </div> ); })}
Fondamentalement, ce que je dois faire est de regrouper les liens / objets par catégorie afin que je puisse les rendre avec le titre de la catégorie correspondante. p>
J'aurai besoin d'un nouveau tableau pour être comme ceci:
export const NEWDummyLinkRows = [ { category: { name: 'Social' }, links: [ { name: 'Facebook', url: 'https://www.facebook.com' }, { name: 'Instagram', url: 'https://www.instagram.com' } ] }, { category: { name: 'Human Resources' }, links: [ { name: 'Other HR', url: 'https://www.hr.com' }, { name: 'Zebra HR', url: 'https://www.zebra.com' } ] }, ];
Voici ce que j'ai jusqu'à présent dans une méthode de rendu de réaction:
const dummyLinkRows = [ { id: 'entity:link/1:en', categories: [ { name: 'Human Resources' }, { name: 'Social' } ], name: 'Facebook', url: 'https://www.facebook.com' }, { id: 'entity:link/2:en', categories: [ { name: 'Human Resources' } ], name: 'Other HR', url: 'https://www.hr.com' }, { id: 'entity:link/3:en', categories: [ { name: 'Zen Mode' } ], name: 'Zebra', url: 'https://www.zebra.com' }, { id: 'entity:link/4:en', categories: [ { name: 'Social' } ], name: 'Zebra', url: 'https://www.instagram.com' }, ];
Jusqu'à présent, il restitue les données mais pas comme j'en ai besoin. La méthode dont j'ai besoin pourrait utiliser ES6 / JavaScript pur.
5 Réponses :
Une solution pourrait être de d'abord réduire à un objet, puis de mapper les entrées de l'objet à votre résultat attendu:
const rows = [{ id: 'entity:link/1:en', categories: [{ name: 'Human Resources' }, { name: 'Social' } ], name: 'Facebook', url: 'https://www.facebook.com' }, { id: 'entity:link/2:en', categories: [{ name: 'Human Resources' }], name: 'Other HR', url: 'https://www.hr.com' }, { id: 'entity:link/3:en', categories: [{ name: 'Zen Mode' }], name: 'Zebra', url: 'https://www.zebra.com' }, { id: 'entity:link/4:en', categories: [{ name: 'Social' }], name: 'Zebra', url: 'https://www.instagram.com' } ]; const result = Object.entries(rows.reduce((a, {name, url, categories}) => { categories.forEach(c => { a[c.name] = a[c.name] || []; a[c.name].push({name, url}); }); return a; }, {})).map(([name, links]) => ({ category: {name}, links })); console.log(result);
Extrait complet:
const result = Object.entries(rows.reduce((a, {name, url, categories}) => { categories.forEach(c => { a[c.name] = a[c.name] || []; a[c.name].push({name, url}); }); return a; }, {})).map(([name, links]) => ({ category: {name}, links }));
Essayez (h = {})
const dummyLinkRows = [ { id: 'entity:link/1:en', categories: [ { name: 'Human Resources' }, { name: 'Social' } ], name: 'Facebook', url: 'https://www.facebook.com' }, { id: 'entity:link/2:en', categories: [ { name: 'Human Resources' } ], name: 'Other HR', url: 'https://www.hr.com' }, { id: 'entity:link/3:en', categories: [ { name: 'Zen Mode' } ], name: 'Zebra', url: 'https://www.zebra.com' }, { id: 'entity:link/4:en', categories: [ { name: 'Social' } ], name: 'Zebra', url: 'https://www.instagram.com' }, ]; let h={}; dummyLinkRows.forEach(x=> x.categories.forEach(c=> h[c.name]=(h[c.name]||[]).concat([{name:x.name, url:x.url}]) ) ) let NEWDummyLinkRows = Object.keys(h).map(k=> ({category:k, links: h[k]}) ) console.log(NEWDummyLinkRows);
dummyLinkRows.forEach(x=> x.categories.forEach(c=> h[c.name] = (h[c.name]||[]).concat([{name:x.name, url:x.url}]) )) let NEWDummyLinkRows = Object.keys(h).map(k=> ({category:k, links: h[k]}) )
Vous pouvez utiliser réduire
et Map
const dummyLinkRows = [{id: 'entity:link/1:en',categories: [{name: 'Human Resources'},{name: 'Social'}],name: 'Facebook',url: 'https://www.facebook.com'},{id: 'entity:link/2:en',categories: [{name: 'Human Resources' }],name: 'Other HR',url: 'https://www.hr.com'},{id: 'entity:link/3:en',categories: [{name: 'Zen Mode'}],name: 'Zebra',url: 'https://www.zebra.com'},{id: 'entity:link/4:en',categories: [{name: 'Social'}],name: 'Zebra',url: 'https://www.instagram.com'}]; const final = dummyLinkRows.reduce((op,inp) => { let {name: nameOuter, categories, url} = inp categories.forEach(({name}) => { if(op.has(name)){ op.get(name).links.push({name: nameOuter, url}) } else{ op.set(name, {catgeory:{name}, links:[{name:nameOuter, url}] }) } }) return op },new Map()) console.log([...final.values()])
Je pense que le meilleur moyen est d'utiliser réduire . Vous appelez .reduce
sur un tableau, passez-lui une fonction et un objet de départ. La fonction prend les paramètres «précédent» (la valeur précédente) et «courant» (la valeur actuelle du tableau) et renvoie le résultat, qui sera «précédent» pour le prochain appel à la fonction et le résultat final après le dernier appel. Prenez donc l'un de vos éléments:
let final = Object.keys(intermediate).map(key => { return { category: { name: key }, links: intermediate[key]; }; });
Vous semblez vouloir un tableau d'objets avec une propriété d'objet de catégorie et une liste d'objets avec une propriété em> de la catégorie qui est un objet avec un nom et une liste de liens avec un nom et une url. Je pense que les objets résultants devraient être des catégories elles-mêmes avec juste un nom, mais peu importe. Dans un premier temps, vous devez rendre les catégories uniques. Un objet javascript est parfait pour cela, les noms de propriétés étant vos clés. Donc, cet exemple finirait par être converti en:
intermediate = { "Human Resources": { links: [ { name: 'Facebook', url: 'https://www.facebook.com' } ] }, "Social": { links: [ { name: 'Facebook', url: 'https://www.facebook.com' } ] } }
Nous pouvons donc commencer avec un objet vide. Cela aura une propriété avec le nom de chaque catégorie, et la valeur de cette propriété sera un objet avec un tableau d'objets 'links' avec le nom et l'url du lien. Donc pour chaque élément de votre tableau d'origine, nous créons une propriété si elle n'existe pas comme {links: []}
Si l'objet existe déjà, nous l'utilisons. Ensuite, nous ajoutons le nouveau lien au tableau 'links'.
function reducer(previous, current) { // previous will start as empty object and become our result, current // is the current element of the array we are processing // loop through each category current.categories.forEach(category => { // create a new object with links array if the category doesn't exist previous[category.name] = previous[category.name] || { links: [] }; // add link to category previous[category.name].links.push({ name: current.name, url: current.url }); }); // return 'previous' which is our ongoing object we're creating return previous; } // call reducer for each element of our array, starting with an empty object let intermediate = dummyLinkRows.reduce(reducer, {});
Maintenant vous avez:
{ "Human Resources": { links: [ { name: 'Facebook', url: 'https://www.facebook.com' } ] }, "Social": { links: [ { name: 'Facebook', url: 'https://www.facebook.com' } ] } }
Donc nous ' J'ai créé un objet unique pour chaque catégorie. Pour obtenir votre tableau final, vous voulez un élément pour chaque catégorie avec une propriété 'category' qui est un objet avec le nom et notre tableau de liens. Nous pouvons donc utiliser Object.keys pour obtenir la liste des noms de catégories (noms de propriétés de l'objet). Utilisation de map () pour convertir ces clés en objets de votre choix:
{ id: 'entity:link/1:en', categories: [ { name: 'Human Resources' }, { name: 'Social' } ], name: 'Facebook', url: 'https://www.facebook.com' },
De manière native, vous pouvez simplement y parvenir comme ceci
const array = [ { id: 'entity:link/1:en', categories: [ { name: 'Human Resources', }, { name: 'Social', }, ], name: 'Facebook', url: 'https://www.facebook.com', }, { id: 'entity:link/2:en', categories: [ { name: 'Human Resources', }, ], name: 'Other HR', url: 'https://www.hr.com', }, { id: 'entity:link/3:en', categories: [ { name: 'Zen Mode', }, ], name: 'Zebra', url: 'https://www.zebra.com', }, { id: 'entity:link/4:en', categories: [ { name: 'Social', }, ], name: 'Zebra', url: 'https://www.instagram.com', }, ]; const filteredArry = []; for (let i = 0; i < array.length; i += 1) { const element = array[i]; const { categories } = element; if (categories && Array.isArray(categories)) { for (let j = 0; j < categories.length; j += 1) { const cats = categories[j]; const index = filteredArry.findIndex((r) => { return r.catgeory && r.catgeory.name === cats.name; }); if (index === -1) { const obj = { catgeory: { name: cats.name }, links: [{ name: element.name, url: element.url }], }; filteredArry.push(obj); } else { const obj = { name: element.name, url: element.url }; filteredArry[index].links.push(obj); } } } } console.log(filteredArry);
pour le lien
instagram
, vous avez le nom commezèbre
mais dans la sortie souhaitée, c'est commeInstagram
je considère cela comme une faute de frappe, veuillez mettre à jour la question