这就是所谓的装箱问题
解决方案将取决于您对高效的定义,更高效的装箱往往需要更长的时间来计算。但是效率较低的装箱往往会占用更少的计算资源(在计算资源方面可能被认为更有效)。
这是我使用 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 上