我有一个包含1500个varint字符串的数组,如下所示:
var base = ["129;176;2","131;173;2","242;1","221;188;2","138;7","201;20","251;12","32"]
数组的字符串可以由一个数字(" 32"),两个数字(" 242; 1")或三个数字(" 131; 173; 2"),不超过3个数字。
一个变量,包含从数组中包含的字符串的串联中获取的字符串(该变量由用户创建,并且只能从可在基础数组中找到的值列表中创建)。
var userCreated = "129;176;2;32;131;173;2;184;3;201;20;251;12"
问题是在阵列中找到一个完美的匹配,但我不知道要检查的正确部分。
例如: 我不知道我是否能匹配" 129"或" 129; 176"或" 129; 176; 2",所以我需要一个能匹配第一个数字,第一个和第二个数字,以及第一个,第二个和第三个数字的函数。当找到完美匹配时,字符串的一部分必须存储在一个新变量中,并从原始变量(userCreated)中删除。
只需一个号码即可:
var divide = userCreated.split(";");
for (var i = 0;i<divide.length; i++){
if(base.indexOf(divide[i]) >= 0){
var found + i = divide[i];
}
}
可以按顺序检查var中对数组的字符串以找到完美匹配,然后检查字符串的其余部分?重要的是要注意:匹配可以在&#34;完美匹配之前找到&#34; (检查&#34; 129&#34;可以找到匹配,但基本数组中可能有&#34; 129; 176&#34;(完美匹配),因此其他值可能不匹配...
修改 澄清问题:userCreated字符串不能包含两次要在数组中匹配的值。例如:它可以包含126; 15和126; 15; 2但不包括126; 15或126; 15; 2两次。 预期结果可以是一系列变量,内部每个&#34;完美匹配&#34;,例如:
var found0 = "129;176;2";
var found1 = "242;1";
var found2 = "32";
或像原始数组一样的数组:
var found = ["129;176;2", "242;1", "32"] // Maybe a better solution
从1场比赛到30场比赛的总比赛数量。
编辑(解决方案): 在接受(和好)答案后,我尝试按照类似的方式: 我将原始数组拆分为3个数组,如下所示:
base1 = ["28", "34", "16"];
base2 = ["125;16", "200;45", "167;2"];
base3 = ["209;145;2", "143;154;2", "211;170;2", "246;170;2", "247;170;2"];
然后:
var divide = userCreated.split(";"),
resultArray3 = [], resultArray2 = [], resultArray1 = [], final = [];
function tri(divide){
for (var i = 0, j = 1, k = 2; k<divide.length; i++, j++, k++){
var tre = base3.indexOf(divide[i]+';'+divide[j]+';'divide[k]);
if (tre !== -1){
resultArray3.push(base3[tre]);
divide.splice(i, 1, "none");
divide.splice(j, 1, "none");
divide.splice(k, 1, "none");
}
}
}
function two(divide){
for (var i = 0, k = 1; k<divide.length; i++, k++){
var due = base2.indexOf(divide[i]+';'+divide[k]);
if (due !== -1){
resultArray2.push(base2[due]);
divide.splice(i, 1, "none");
divide.splice(k, 1, "none");
}
}
}
function ones(divide){
for (var k = 0; k<divide.length; k++){
var uno = base1.indexOf(divide[k]);
if (uno !== -1){
resultArray1.push(base1[uno]);
divide.splice(k, 1, "none");
}
}
}
最后:
final.push.apply(final, resultArray1);
final.push.apply(final, resultArray2);
final.push.apply(final, resultArray3);
答案 0 :(得分:0)
正如@ObsidianAge所指出的,可能有多种方法将输入字符串拆分为匹配部分。如果可能的话,我会检查输入是否必须这样。
我不确定是什么阻止了你追求你所描述的解决方案......最简单的实现涉及递归:
let base = ["129", "129;176", "129;176;2","131;173;2","242;1","221;188;2","138;7","201;20","251;12","32", "184;3", "176"]
let userCreated = '129;176;2;32;131;173;2;184;3;201;20;251;12';
let appendSemicolon = (str) => str + ";";
let removeSemicolon = (str) => str.substr(0, str.length-1);
base = base.map(appendSemicolon); // so that '1' is not matched as a prefix of '12;34'
function findMatch(input, depth=0) {
// returns an array of arrays where:
// solutions[i].join("") == input
// solutions[i][j] is a string from `base`
// (empty array if no such solutions exist)
let solutions = [];
base.forEach((prefix) => {
if (!input.startsWith(prefix)) return;
let rest = input.substr(prefix.length);
if (rest.length === 0) {
// easy case: the input has a 'perfect match' in `base`
console.log(" ".repeat(depth) + `checking '${prefix}' - matching complete!`)
solutions.push([prefix]);
} else {
// we found a matching prefix. It will be a valid solution iff
// the rest of input can be constructed from the strings in `base`
console.log(" ".repeat(depth) + `checking '${prefix}' (rest='${rest}')`)
let subSolutions = findMatch(rest, depth+1);
solutions = solutions.concat(subSolutions.map((sol) => [prefix].concat(sol)));
}
});
return solutions;
}
findMatch(userCreated + ";").map((parts) => parts.map(removeSemicolon));
请注意,您没有指定输入字符串中是否允许重复条目,我不是要尝试优化它,而是使用JS的新版本中的一些语法,这些语法可能不受普遍支持所有的浏览器。