【问题标题】:Remove duplications and sort array by most frequent tags删除重复项并按最常见的标签对数组进行排序
【发布时间】:2020-03-31 15:31:10
【问题描述】:

我有一组对象。该对象具有标签数组。

例如:

const tags =
[{
      id:"1,
      Category: "Food"
      tags: ["One", "Two", "Three"],
},
{
      id:"2,
      Category: "Drinks"
      tags: ["Four", "Five", "Six"],
},
{
      id:"3,
      Category: "Herbs"
      tags: ["One", "Two", "Three"], // These tags are duplication of the first object and should not be in final list of tags (output).
}];

我的 JSX 代码示例:

tags.map(tags =>
        [...new Set(tags.tags)] // ?? I was playing with set, because I need delete duplications and also sort the final output by most frequent used tags
          .map(tag => (
            <Link to={"/" + tags.category + "/" + tag}>
              {tag}
            </Tag>
          ))
      )

我正在尝试删除最终输出标签列表中的重复标签。正如您在我的代码中看到的那样,我尝试过的解决方案之一是 [...new Set(tags.tags)] - 因为我需要两件事 = 1) 对最常用的标签进行排序并删除重复项。此解决方案适用于排序(简单数组适用于两者),但由于对象数组,仍然存在重复。我在 codepen 中尝试了 SET 的一些魔法,但没有成功。你知道如何解决它吗?我知道有 lodash,但我更愿意使用没有 lib 的自己的解决方案。谢谢!

【问题讨论】:

  • 应该使用哪个类别,例如One - FoodHerbs?
  • 没关系:因为我只需要输出(过滤,排序..)标签的简单列表。 :)

标签: javascript function sorting mapping filtering


【解决方案1】:

将数组简化为 Map,如果标签在 Map 中,则使用Array.forEach() 添加标签及其类别,并计算标签的出现次数(freq)。转换成[tag, { freq, category }]对的数组,按freq排序,映射到JSX:

const { useMemo } = React;

const getTagsWithCategories = tags => Array.from(
  tags.reduce((r, o) => {
    o.tags.forEach(tag => {
      if(!r.has(tag)) r.set(tag, { category: o.Category, freq: 0 }); // init      
      r.get(tag).freq++; // increase freq
    });
  
    return r;
  }, new Map()))
  .sort(([, a], [, b]) => b.freq - a.freq) // sort by freq

const Tags = ({ tags }) => {
  const pairs = useMemo(() => getTagsWithCategories(tags), [tags]);

  return pairs.map(([tag, { category }]) => (
    <a href={`/${category}/${tag}`} key={tag}>
    {tag}
    </a>
  ))
};

const tags = [{"id":1,"Category":"Food","tags":["One","Two","Three"]},{"id":2,"Category":"Drinks","tags":["Four","Five","Six"]},{"id":3,"Category":"Herbs","tags":["One","Two","Three"]}];

ReactDOM.render(
  <Tags tags={tags} />,
  root
);
a:not(:last-child) {
  margin-right: 1em;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>

<div id="root"></div>

【讨论】:

    猜你喜欢
    • 2021-11-20
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2021-12-18
    • 2013-12-03
    • 2015-06-18
    • 2014-11-05
    相关资源
    最近更新 更多