[英]How can I create a new array from an array of objects filter by one value?
所以我有這個對象數組:
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'
},
];
基本上,我需要做的是按類別對鏈接/對象進行分組,以便為它們呈現對應的類別標題。
我將需要一個新的數組,像這樣:
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'
}
]
},
];
到目前為止,這是我在react render方法中所擁有的:
{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>
);
})}
到目前為止,它可以呈現數據,但不是我需要的。 我需要的方法可能是使用純ES6 / JavaScript。
一種解決方案可能是首先還原為一個對象,然后將該對象的條目映射到您的預期結果:
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 }));
完整代碼段:
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);
您可以使用reduce
和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()])
我認為最好的方法是使用reduce 。 您在數組上調用.reduce
,將一個函數傳遞給起始對象。 該函數接受參數“ previous”(上一個值)和“ current”(當前數組值)並返回結果,該結果對於下一次調用該函數將是“ previous”,而在最后一次調用之后將是最終結果。
因此,請采用您的元素之一:
{
id: 'entity:link/1:en',
categories: [
{
name: 'Human Resources'
},
{
name: 'Social'
}
],
name: 'Facebook',
url: 'https://www.facebook.com'
},
你似乎想的對象與類別對象屬性的數組和對象與類別的屬性 ,它是一個名稱以及與名稱和URL鏈接列表的對象列表。 我認為生成的對象應該是僅帶有名稱的類別本身,但不管怎樣。 第一步,您需要使類別唯一。 一個javascript對象非常適合此操作,屬性名稱是您的鍵。 因此,此示例最終將轉換為:
{
"Human Resources": {
links: [
{ name: 'Facebook', url: 'https://www.facebook.com' }
]
},
"Social": {
links: [
{ name: 'Facebook', url: 'https://www.facebook.com' }
]
}
}
因此,我們可以從一個空對象開始。 該屬性將具有每個類別的名稱,並且該屬性的值將是帶有“鏈接”對象數組的對象,其中包含鏈接的名稱和網址。 因此,對於原始數組中的每個元素,如果不存在,則會創建一個屬性,例如{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, {});
現在您有了:
intermediate = {
"Human Resources": {
links: [
{ name: 'Facebook', url: 'https://www.facebook.com' }
]
},
"Social": {
links: [
{ name: 'Facebook', url: 'https://www.facebook.com' }
]
}
}
因此,我們為每個類別創建了一個唯一的對象。 為了獲得最終的數組,您需要為每個類別都具有“ category”屬性的項目,該屬性是具有名稱和我們的links數組的對象。 因此,我們可以使用Object.keys來獲取類別名稱(對象的屬性名稱)的列表。 使用map()將這些鍵轉換為所需的對象:
let final = Object.keys(intermediate).map(key => {
return {
category: { name: key },
links: intermediate[key];
};
});
以一種本機的方式,您可以像這樣簡單地實現它
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);
試試(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]}) )
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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.