Создайте строку переменной длины, заполненную повторяющимся символом
Итак, мой вопрос был задан кем-то другим в нем. Форма Java здесь: Java. Создайте новый экземпляр String с указанной длиной и заполните конкретным символом. Лучшее решение?
., но я ищу его эквивалент JavaScript.
В принципе, я хочу динамически заполнять текстовые поля символами "#" на основе атрибута "maxlength" каждого поля. Итак, если вход имеет maxlength="3"
, тогда поле будет заполнено "###".
В идеале будет что-то вроде Java StringUtils.repeat("#", 10);
, но до сих пор лучшим вариантом, о котором я могу думать, является цикл и добавление символов "#" , по одному за раз, пока максимальная длина не будет достиг. Я не могу поколебать ощущение, что есть более эффективный способ сделать это, чем это.
Любые идеи?
FYI - я не могу просто установить значение по умолчанию на входе, потому что символы "#" должны очистить фокус, и, если пользователь не вводит значение, нужно будет "пополнить" стираться. Это шаг "пополнения", который мне связан с
Ответы
Ответ 1
Лучший способ сделать это (что я видел)
var str = new Array(len + 1).join( character );
Это создает массив с заданной длиной, а затем соединяет его с заданной строкой для повторения. Функция .join()
выполняет оценку длины массива независимо от того, имеют ли элементы назначенные значения, а значения undefined отображаются как пустые строки.
Вы должны добавить 1 к требуемой длине, потому что строка разделителя находится между элементами массива.
Ответ 2
Попробуйте: P
s = '#'.repeat(10)
document.body.innerHTML = s
Ответ 3
К сожалению, хотя описанный здесь подход Array.join является кратким, он примерно на 10 раз медленнее, чем реализация на основе строковой конкатенации. Особенно сильно это происходит на больших струнах. Подробнее см. Ниже.
В Firefox, Chrome, Node.js MacOS, Node.js Ubuntu и Safari, самая быстрая реализация, которую я тестировал:
function repeatChar(count, ch) {
if (count == 0) {
return "";
}
var count2 = count / 2;
var result = ch;
// double the input until it is long enough.
while (result.length <= count2) {
result += result;
}
// use substring to hit the precise length target without
// using extra memory
return result + result.substring(0, count - result.length);
};
Это многословно, поэтому, если вам нужна краткая реализация, вы можете пойти с наивным подходом; он все еще выполняет betweeb от 2X до 10X лучше, чем метод Array.join, а также быстрее, чем реализация удвоения для небольших входов. Код:
// naive approach: simply add the letters one by one
function repeatChar(count, ch) {
var txt = "";
for (var i = 0; i < count; i++) {
txt += ch;
}
return txt;
}
Дополнительная информация:
Ответ 4
Я бы создал константную строку, а затем вызывал подстроку на ней.
Что-то вроде
var hashStore = '########################################';
var Fiveup = hashStore.substring(0,5);
var Tenup = hashStore.substring(0,10);
Еще немного быстрее.
http://jsperf.com/const-vs-join
Ответ 5
Версия, которая работает во всех браузерах
Эта функция делает то, что вы хотите, и выполняет намного быстрее, чем вариант, предложенный в принятом ответе:
var repeat = function(str, count) {
var array = [];
for(var i = 0; i <= count;)
array[i++] = str;
return array.join('');
}
Вы используете его следующим образом:
var repeatedCharacter = repeat("a", 10);
Чтобы сравнить производительность этой функции с параметром, предложенным в принятом ответе, см. this Fiddle и этот скрипт для тестов.
Версия для современных браузеров
В современных браузерах вы также можете сделать это:
var repeatedCharacter = "a".repeat(10) };
Эта опция еще быстрее. Однако, к сожалению, он не работает ни в одной версии Internet Explorer.
Цифры в таблице определяют первую версию браузера, полностью поддерживающую метод:
![введите описание изображения здесь]()
Ответ 6
For Evergreen browsers, this will build a staircase based on an incoming character and the number of stairs to build.
function StairCase(character, input) {
let i = 0;
while (i < input) {
const spaces = " ".repeat(input - (i+1));
const hashes = character.repeat(i + 1);
console.log(spaces + hashes);
i++;
}
}
//Implement
//Refresh the console
console.clear();
StairCase("#",6);
Вы также можете добавить polyfill для повтора для старых браузеров
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
// Could we try:
// return Array(count + 1).join(this);
return rpt;
}
}
Ответ 7
Основываясь на ответах Хогана и Зеро Трика Пони. Я думаю, что это должно быть как быстрым, так и гибким, чтобы хорошо справляться с большинством случаев:
var hash = '####################################################################'
function build_string(length) {
if (length == 0) {
return ''
} else if (hash.length <= length) {
return hash.substring(0, length)
} else {
var result = hash
const half_length = length / 2
while (result.length <= half_length) {
result += result
}
return result + result.substring(0, length - result.length)
}
}
Ответ 8
Хорошо, я думаю, это то, что вы ищете.
Вы можете увидеть, как он был реализован в node.js src:
function repeatString(str, len) {
return Array.apply(null, {
length: len + 1
}).join(str).slice(0, len)
}
Ответ 9
Вы можете использовать первую строку функции как однострочный, если хотите:
function repeat(str, len) {
while (str.length < len) str += str.substr(0, len-str.length);
return str;
}