例如,如果我在变量中有"scissors"
并且想要知道所有出现的字母"s"
的位置,那么它应打印出1, 4, 5, 8
如何以最有效的方式在JavaScript中执行此操作?我不认为循环整体是非常有效的
答案 0 :(得分:74)
一个简单的循环效果很好:
var str = "scissors";
var indices = [];
for(var i=0; i<str.length;i++) {
if (str[i] === "s") indices.push(i);
}
现在,您表明您想要1,4,5,8。这将为您提供0,3,4,7,因为索引从零开始。所以你可以添加一个:
if (str[i] === "s") indices.push(i+1);
现在它会给你预期的结果。
小提琴可以看here。
我不认为循环整体非常有效
就性能而言,我认为在您开始遇到问题之前,您需要非常担心这一点。
这是一个比较各种答案的jsPerf测试。在Safari 5.1中,IndexOf表现最佳。在Chrome 19中,for循环是最快的。
答案 1 :(得分:20)
使用原生String.prototype.indexOf
方法最有效地查找每个偏移量。
function locations(substring,string){
var a=[],i=-1;
while((i=string.indexOf(substring,i+1)) >= 0) a.push(i);
return a;
}
console.log(locations("s","scissors"));
//-> [0, 3, 4, 7]
然而,这是一种微观优化。对于一个足够快的简单而简洁的循环:
// Produces the indices in reverse order; throw on a .reverse() if you want
for (var a=[],i=str.length;i--;) if (str[i]=="s") a.push(i);
事实上,使用indexOf
的chrome上的原生循环更快!
答案 2 :(得分:8)
当我对所有内容进行基准测试时,似乎正则表达式表现得最好,所以我想出了这个
function indexesOf(string, regex) {
var match,
indexes = {};
regex = new RegExp(regex);
while (match = regex.exec(string)) {
if (!indexes[match[0]]) indexes[match[0]] = [];
indexes[match[0]].push(match.index);
}
return indexes;
}
你可以这样做
indexesOf('ssssss', /s/g);
会返回
{s: [0,1,2,3,4,5]}
我需要一种非常快速的方法来匹配多个字符与大量文本,例如你可以这样做
indexesOf('dddddssssss', /s|d/g);
你会得到这个
{d:[0,1,2,3,4], s:[5,6,7,8,9,10]}
这样你就可以一次性获得你所有比赛的所有索引
答案 3 :(得分:7)
function charPos(str, char) {
return str
.split("")
.map(function (c, i) { if (c == char) return i; })
.filter(function (v) { return v >= 0; });
}
charPos("scissors", "s"); // [0, 3, 4, 7]
请注意,JavaScript从0开始计算。如果必须,请将+1添加到i
。
答案 4 :(得分:5)
更多功能乐趣,也更通用:它在字符串中找到任何长度子字符串的起始索引
const length = (x) => x.length
const sum = (a, b) => a+b
const indexesOf = (substr) => ({
in: (str) => (
str
.split(substr)
.slice(0, -1)
.map(length)
.map((_, i, lengths) => (
lengths
.slice(0, i+1)
.reduce(sum, i*substr.length)
))
)
});
console.log(indexesOf('s').in('scissors')); // [0,3,4,7]
console.log(indexesOf('and').in('a and b and c')); // [2,8]
答案 5 :(得分:2)
indices = (c, s) => s
.split('')
.reduce((a, e, i) => e === c ? a.concat(i) : a, []);
indices('?', 'a?g??'); // [1, 3, 4]
答案 6 :(得分:1)
您也可以使用javascript的match()函数。您可以创建正则表达式,然后将其作为参数传递给match()。
stringName.match(/s/g);
这应该返回一个字母's'的所有出现的数组。
答案 7 :(得分:1)
使用while循环
collect(Server::all())->keyBy('id')
答案 8 :(得分:1)
另一种选择是使用 flatMap
。
var getIndices = (s, t) => {
return [...s].flatMap((char, i) => (char === t ? i + 1 : []));
};
console.log(getIndices('scissors', 's'));
console.log(getIndices('kaios', '0'));
答案 9 :(得分:0)
我喜欢这个问题,并想通过使用在数组上定义的reduce()
方法来写我的答案。
function getIndices(text, delimiter='.') {
let indices = [];
let combined;
text.split(delimiter)
.slice(0, -1)
.reduce((a, b) => {
if(a == '') {
combined = a + b;
} else {
combined = a + delimiter + b;
}
indices.push(combined.length);
return combined; // Uncommenting this will lead to syntactical errors
}, '');
return indices;
}
let indices = getIndices(`Ab+Cd+Pk+Djb+Nice+One`, '+');
let indices2 = getIndices(`Program.can.be.done.in.2.ways`); // Here default delimiter will be taken as `.`
console.log(indices); // [ 2, 5, 8, 12, 17 ]
console.log(indices2); // [ 7, 11, 14, 19, 22, 24 ]
// To get output as expected (comma separated)
console.log(`${indices}`); // 2,5,8,12,17
console.log(`${indices2}`); // 7,11,14,19,22,24
答案 10 :(得分:0)
只是进一步的解决方案,这是我的解决方案: 您可以找到字符串中存在的字符索引:
findIndex(str, char) {
const strLength = str.length;
const indexes = [];
let newStr = str;
while (newStr && newStr.indexOf(char) > -1) {
indexes.push(newStr.indexOf(char) + strLength- newStr.length);
newStr = newStr.substring(newStr.indexOf(char) + 1);
}
return indexes;
}
findIndex('scissors', 's'); // [0, 3, 4, 7]
findIndex('Find "s" in this sentence', 's'); // [6, 15, 17]
答案 11 :(得分:0)
这是使用函数表达式(带有ES6箭头函数)的简短解决方案。该函数接受字符串和要查找的字符作为参数。它将字符串拆分为一个字符数组,并使用reduce
函数累积匹配的索引并将其作为数组返回。
const findIndices = (str, char) =>
str.split('').reduce((indices, letter, index) => {
letter === char && indices.push(index);
return indices;
}, [])
测试:
findIndices("Hello There!", "e");
// → [1, 8, 10]
findIndices("Looking for new letters!", "o");
// → [1, 2, 9]
这是一个紧凑的(单行)版本:
const findIndices = (str, char) => str.split('').reduce( (indices, letter, index) => { letter === char && indices.push(index); return indices }, [] );