【问题标题】:Logic to auto generate alphabet groups自动生成字母组的逻辑
【发布时间】:2021-07-10 06:14:49
【问题描述】:

我有一个包含单词及其含义的 Dictionary 部分的 React App 应用程序。

目前由一个按字母顺序排列的导航栏组成,A、B、C、D 等一直到 Z,例如,如果您单击 C,则它会向下滚动到 C 部分并显示所有 C 单词。

导航栏是静态的,其中包含一个数组,其中包含 ['A', 'B'...] 一直到 'Z' i,但是这些部分是根据可用的单词自动(动态)生成的。

 let data = posts.reduce((r, e, index) => {

            let group = e.title[0];
            group.normalize("NFD").replace(/[\u0300-\u036f]/g, "");

            group.toUpperCase();

            group = findSectionLetter(group);

            if (!r[group]) r[group] = { group, children: [e] }
            else r[group].children.push(e);

            return r;

        }, {}); 

然后我使用setGroups(Object.entries(data)); 将数据添加到状态,它会输出一个数组,例如[ ... ["B", {children: [..wordlist..], group: "B"}....] 等,这是完美的原因,现在我可以循环遍历它并且可以相对轻松地实现 [{A, {actor, adam , apple}}, {B, {blue, bob, bunny}] 等在我的模板上。

所以我想对导航栏做类似的事情,索引列表现在有整个字母表,例如 A、B、C、D,如果带有字母的单词不存在,一些链接将不起作用,它看起来缺少字母很有趣,我想根据可用的内容动态生成,并根据不可用的内容进一步分组..例如,

如果单词是“Adam, Bob, Charley”(A, B, C)并且后面的单词是“George”(意思是没有 E & F),它应该创建组 CG 以避免导航栏看起来太空。

我的计划是匹配索引值,但我不确定我的方向是否正确。

有什么建议吗?

【问题讨论】:

  • BTW、normalizereplacetoUpperCase 不会改变原始字符串。您需要将它们重新分配给group
  • 顺便说一句,group.toUpperCase(); 没有分配就无法工作。字符串是不可变的。

标签: javascript reactjs logic grouping reducers


【解决方案1】:

我建议预先计算您的字母组并将其作为初始值传递给帖子减少。

const groups = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("").reduce(
  (groups, ch) => ({
    ...groups,
    [ch]: { children: [] }
  }),
  {}
);

console.log(groups);

注意:normalizereplacetoUpperCase 都返回新字符串,因此可以将它们链接起来。这还假设所有 title 字符串值的长度至少为 1 个字符。

let data = posts.reduce((r, e, index) => {
  const group = e.title[0]
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toUpperCase();

  groupKey = findSectionLetter(group);

  r[groupKey].children.push(e); // <-- push into group array

  return r;
}, groups); // <-- initialize with groups already made

【讨论】:

    【解决方案2】:

    只需初始化组即可为所有字母创建一个条目。您可能还应该为任何不以字母开头的标题做一个“包罗万象”。例如,“-”可能就是全部。

    还将组数据结构做成字典(普通对象),以便在恒定时间内访问给定字母的组,而无需在数组中搜索。

    当您从一开始就拥有所有条目时,您不再需要.reduce()。相反,for 循环足以遍历帖子以填充组。

    let groups = Object.fromEntries(Array.from("-ABCDEFGHIJKLMNOPQRSTUVWXYZ", group => [
        group, 
        { children: [], group }
    ]));
    
    // Sample data
    let posts = [{title: "Astrophysics"}, {title: "Biology"},
                 {title: "Chemistry"}, {title: "### Something else ###"}];
    
    for (let e of posts) {
        let letter = e.title[0]
            .normalize("NFD").replace(/[^a-z]/gi, "-") // Anything that's not a Latin letter
            .toUpperCase();
        groups[letter].children.push(e);
    }
    
    groups = Object.entries(groups); // Optional: In case you prefer the array of pairs.
    
    console.log(groups);

    【讨论】:

      猜你喜欢
      • 2015-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-13
      相关资源
      最近更新 更多