2

我有很多这样的名字:

namelist = [ "Andrew Alexander Brown", "Charlie Christopher Drake", "Edward Elsevier Furlong", "Gareth Gates Harper", "Indiana Chewbacca Jones", "Kevin M Lamarr", "Michael Randy Newman", "Oliver Terry Pratchett", "Queen Liz Regina", "Stuart Townsend", "Umar Vespa", "Woodford X Xanadu", "Yanick Zebra" ];

我想将列表中的名称提取为字符串,每个名称用管道字符 (|) 分隔。每个新字符串应小于 48 个字符,例如输出应如下所示(但小于或等于 48 个字符):

Andrew Alexander Brown|Charlie Christopher Drake|Edward Elsevier Furlong
Gareth Gates Harper|Indiana Chewbacca Jones|Kevin M Lamarr
Michael Randy Newman|Oliver Terry Pratchett|Queen Liz Regina
Stuart Townsend|Umar Vespa|Woodford X Xanadu|Yanick Zebra

我希望新字符串的数量尽可能少,可能不维护数组中字符串的顺序 - 但我不知道如何在 javascript 中执行此操作。

我知道我可以做一些事情,比如遍历名单并将下一个名称添加到临时字符串中。检查此临时字符串的长度,如果超过 48 个字符则输出。继续循环,直到我们用完名称,但这似乎不是很有效。例如,如果一个短名称后跟一个非常长的名称,那么字符(可以在临时字符串中由另一个较小的名称填充)将被浪费。

关于如何最好地实现这一目标的任何指示?

4

2 回答 2

3

这就是所谓的装箱问题

解决方案将取决于您对高效的定义,更高效的装箱往往需要更长的时间来计算。但是效率较低的装箱往往会占用更少的计算资源(在计算资源方面可能被认为更有效)。

这是我使用 ECMA5 规范的解决方案,它牺牲了计算资源以支持更有效的装箱。

我选择将该powerSet功能保留为通用功能,这意味着它可以重复用于其他目的。正如@Bergi 强调的那样,如果您创建了一个包含第一个filter来自joinStringsMaxCharacters

Javascript

一般Power Set功能

function powerSet(array) {
    var lastElement,
        sets;

    if (!array.length) {
        sets = [[]];
    } else {
        lastElement = array.pop();
        sets = powerSet(array).reduce(function (previous, element) {
            previous.push(element);
            element = element.slice();
            element.push(lastElement);
            previous.push(element);

            return previous;
        }, []);
    }

    return sets;
}

辅助函数

function isString(element) {
    return typeof element === 'string';
}

function isNotUsed(element) {
    return this.every(function (u) {
        return u.indexOf(element) === -1;
    });
}

function sumLength(s, el) {
    return s + el.length;
}

带连接字符串的包装箱

function joinStringsMaxCharacters(arrayOfStrings, numberOfCharacters, separator) {
    if (!Array.isArray(arrayOfStrings) || !arrayOfStrings.every(isString)) {
        throw new TypeError('arrayOfStrings is not an array of strings!');
    }

    numberOfCharacters = numberOfCharacters >>> 0;
    if (!separator || !isString(separator)) {
        separator = '|';
    }

    var arrayLength = arrayOfStrings.length;

    return powerSet(arrayOfStrings).filter(function (set) {
        return set.length && (set.length === 1 || set.reduce(sumLength, set.length - 1) <= numberOfCharacters);
    }).sort(function (a, b) {
        return b.reduce(sumLength, b.length) - a.reduce(sumLength, a.length) || b.length - a.length;
    }).reduce(function (used, cur) {
        if (used.reduce(sumLength, 0) < arrayLength && cur.every(isNotUsed, used)) {
            used.push(cur);
        }

        return used;
    }, []).map(function (bin) {
        return bin.join(separator);
    });
}

要打包到 bin 中的字符串数组

var nameList = [
    "Andrew Alexander Brown",
    "Charlie Christopher Drake",
    "Edward Elsevier Furlong",
    "Gareth Gates Harper",
    "Indiana Chewbacca Jones",
    "Kevin M Lamarr",
    "Michael Randy Newman",
    "Oliver Terry Pratchett",
    "Queen Liz Regina",
    "Stuart Townsend",
    "Umar Vespa",
    "Woodford X Xanadu",
    "Yanick Zebra"];

打包垃圾箱并显示每个垃圾箱的内容

joinStringsMaxCharacters(nameList, 48).forEach(function (bin) {
    console.log(bin);
});

输出

    凯文 M 拉马尔|斯图尔特汤森|伍德福德 X 世外桃源
    迈克尔·兰迪·纽曼|丽兹·里贾纳女王|奥马尔·维斯帕
    查理克里斯托弗德雷克|奥利弗特里普拉切特
    爱德华·爱思唯尔·弗隆|印第安纳州丘巴卡·琼斯
    安德鲁·亚历山大·布朗|加雷斯·盖茨·哈珀
    雅尼克斑马

jsFiddle 上

于 2014-02-18T20:30:24.350 回答
0
var namelist= ["Andrew Alexander Brown", "Charlie Christopher Drake", "Edward Elsevier Furlong", "Gareth Gates Harper", "Indiana Chewbacca Jones", "Kevin M Lamarr", "Michael Randy Newman", "Oliver Terry Pratchett", "Queen Liz Regina", "Stuart Townsend", "Umar Vespa", "Woodford X Xanadu", "Yanick Zebra"];

var c48= [], next, temp= '', i= 0, L= namelist.length;
while(i<L){
    next= namelist[i++];
    if((temp+next).length<= 47) temp=temp? temp+'|'+next: next;
    else{
        c48.push(temp);
        temp= next;
    }
}

if(next)c48.push(next);
c48.join('\n')

/*  returned value: (String)
Andrew Alexander Brown|Charlie Christopher Drake
Edward Elsevier Furlong|Gareth Gates Harper
Indiana Chewbacca Jones|Kevin M Lamarr
Michael Randy Newman|Oliver Terry Pratchett
Queen Liz Regina|Stuart Townsend|Umar Vespa
Yanick Zebra
*/
于 2014-02-18T17:48:51.290 回答