5

我正在开发一个包含长列表名称的 Web 应用程序。客户最初希望将名称按字母拆分为divs,以便轻松跳转到列表中的特定名称。

现在,查看列表,客户指出了几个只有一两个名字的字母。他现在想知道,如果每个字母中只有几个名字,我们是否可以组合几个连续的字母。

(请注意,根本不显示没有名称的字母。)

我现在要做的是让数据库服务器返回一个排序列表,然后保留一个包含当前字符的变量。我遍历名称列表,递增字符并在到达每个字母时打印开始和结束div以及标签。ul我知道如何调整这段代码来组合一些字母,但是,我不确定如何处理的一件事是特定的字母组合是否是最好的组合。换句话说,假设我有:

  • A- 12 个名字
  • B- 2 个名字
  • C- 1 个名字
  • D- 1 个名字
  • E- 1 个名字
  • F- 23 个名字

我知道如何与一个团体结束A-C,然后D自己拥有。我正在寻找的是一种有效的方式来实现它A应该单独存在,然后B-D应该在一起。

我不确定从哪里开始看这个。

如果有任何不同,此代码将在 Kohana 框架模块中使用。


2012 年 4 月 4 日更新:

这是我需要的澄清:

假设我在一个组中想要的最少项目数是 30。现在假设字母 A 有 25 个项目,字母 B、C 和 D 各有 10 个项目,字母 E 有 32 个项目。我想不理会A,因为结合B+C+D会更好。组合它们的简单方法是 A+B、C+D+E——这不是我想要的。

换句话说,我需要最接近每组最小值的最佳拟合。

4

4 回答 4

1

如果一封信包含超过 10 个姓名,或者您设置的任何合理限制,请不要将其与下一个合并。但是,如果您开始组合字母,您可能会一直运行直到收集到 15 个左右的名称,只要没有单个字母超过 10 个。这不是一个通用的解决方案,但我会这样解决它。

于 2012-04-04T20:35:44.997 回答
1

我用 PHP 想出了这个函数。它将组合中包含超过 $ammount 名称的字母分组。

function split_by_initials($names,$ammount,$tollerance = 0) {
    $total = count($names);
    foreach($names as $name) {
        $filtered[$name[0]][] = $name;
    }
    $count = 0;
    $key = '';
    $temp = array();
    foreach ($filtered as $initial => $split) {
        $count += count($split);
        $temp = array_merge($split,$temp);
        $key .= $initial.'-'; 
        if ($count >= $ammount || $count >= $ammount - $tollerance) {
            $result[$key] = $temp;
            $count = 0;
            $key = '';
            $temp = array();
        }
    }
    return $result;
}

第三个参数用于当您想将组限制为一个没有指定数量但足够接近的单个字母时。

像我想分成 30 个一组但 a 有 25 个这样的东西,如果您将公差设置为 5,则 A 将被单独留下,其他字母将被分组。

我忘了提,但它返回一个多维数组,其中包含的字母作为键,然后是它包含的名称。就像是

大批
(
    [ABC-] => 数组
        (
            [0] => 班迪斯卑尔根
            [1] => 艾瑞洛厄尔
            [2] => 卡门米兰达
        )
)

这不完全是您所需要的,但我认为它已经足够接近了。

于 2012-04-05T17:30:58.170 回答
0

使用 mrsherman 提出的jsfiddle,我想出了一些可行的方法:http: //jsfiddle.net/F2Ahh/

显然,这将用作伪代码,可以应用一些使其更有效的技术。但这可以完成工作。

于 2012-04-04T07:48:01.793 回答
0

Javascrip 版本:具有排序和符号分组的增强版本

function group_by_initials(names,ammount,tollerance) {
        tolerance=tollerance||0;
        total = names.length;
        var filtered={}
        var result={};
        $.each(names,function(key,value){
            val=value.trim();
            var pattern = /[a-zA-Z0-9&_\.-]/
            if(val[0].match(pattern)) {
                intial=val[0];
            }
            else
            {
                intial='sym';
            }
            if(!(intial in filtered))
                filtered[intial]=[];

            filtered[intial].push(val);
        })
        var count = 0;
        var key = '';
        var temp = [];
        $.each(Object.keys(filtered).sort(),function(ky,value){
            count += filtered[value].length;
            temp = temp.concat(filtered[value])
            key += value+'-'; 
            if (count >= ammount || count >= ammount - tollerance) {
                key = key.substring(0, key.length - 1);
                result[key] = temp;
                count = 0;
                key = '';
                temp = [];
            }
        }) 
        return result;
    }
于 2015-06-05T03:48:10.707 回答