簡體   English   中英

如何從按一個值過濾的對象數組創建一個新數組?

[英]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); 

您可以使用reduceMap

 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM