Разбить большую строку на куски n-размера в JavaScript - PullRequest
172 голосов
/ 12 августа 2011

Я хотел бы разбить очень большую строку (скажем, 10 000 символов) на куски размера N.

Каков наилучший способ с точки зрения производительности сделать это?

Например: "1234567890", разделенное на 2, станет ["12", "34", "56", "78", "90"].

Было бы возможно что-то подобное с использованием String.prototype.match, и если это так, это был бы лучший способ сделатьэто с точки зрения производительности?

Ответы [ 17 ]

380 голосов
/ 12 августа 2011

Вы можете сделать что-то вроде этого:

"1234567890".match(/.{1,2}/g);
// Results in:
["12", "34", "56", "78", "90"]

Метод по-прежнему будет работать со строками, размер которых не является точным кратным размеру куска:

"123456789".match(/.{1,2}/g);
// Results in:
["12", "34", "56", "78", "9"]

В общемдля любой строки, из которой вы хотите извлечь не более n размерных подстрок, вы должны сделать:

str.match(/.{1,n}/g); // Replace n with the size of the substring

Если ваша строка может содержать переводы строки или возврат каретки, вы быdo:

str.match(/(.|[\r\n]){1,n}/g); // Replace n with the size of the substring

Что касается производительности, я опробовал это примерно с 10 тыс. символов, и это заняло чуть больше секунды в Chrome.YMMV.

Это также можно использовать в функции многократного использования:

function chunkString(str, length) {
  return str.match(new RegExp('.{1,' + length + '}', 'g'));
}
28 голосов
/ 06 июня 2012

Итог:

  • match очень неэффективно, slice лучше, на Firefox substr / substring еще лучше
  • match еще более неэффективно для коротких строк (даже с кэшированным регулярным выражением - возможно, из-за времени установки синтаксического анализа регулярного выражения)
  • match еще более неэффективен для больших размеров чанка (вероятно, из-за невозможности «прыгнуть»)
  • для более длинных строк с очень маленьким размером чанка, match превосходит slice в старых IE, но все равно проигрывает во всех других системах
  • jsperf пород
26 голосов
/ 23 марта 2015

Я создал несколько более быстрых вариантов, которые вы можете увидеть на jsPerf .Мой любимый это:

function chunkSubstr(str, size) {
  const numChunks = Math.ceil(str.length / size)
  const chunks = new Array(numChunks)

  for (let i = 0, o = 0; i < numChunks; ++i, o += size) {
    chunks[i] = str.substr(o, size)
  }

  return chunks
}
14 голосов
/ 16 января 2013

Это самое быстрое и эффективное решение:

function chunkString(str, len) {
  var _size = Math.ceil(str.length/len),
      _ret  = new Array(_size),
      _offset
  ;

  for (var _i=0; _i<_size; _i++) {
    _offset = _i * len;
    _ret[_i] = str.substring(_offset, _offset + len);
  }

  return _ret;
}

Сравните его с другими ;Я выиграл:)

9 голосов
/ 20 июня 2018

Сюрприз! Вы можете использовать split для разделения.

var parts = "1234567890 ".split(/(.{2})/).filter(O=>O)

Результаты в [ '12', '34', '56', '78', '90', ' ' ]

4 голосов
/ 12 августа 2011
var str = "123456789";
var chunks = [];
var chunkSize = 2;

while (str) {
    if (str.length < chunkSize) {
        chunks.push(str);
        break;
    }
    else {
        chunks.push(str.substr(0, chunkSize));
        str = str.substr(chunkSize);
    }
}

alert(chunks); // chunks == 12,34,56,78,9
3 голосов
/ 16 июня 2014

Я написал расширенную функцию, поэтому длина фрагмента также может быть массивом чисел, например [1,3]

String.prototype.chunkString = function(len) {
    var _ret;
    if (this.length < 1) {
        return [];
    }
    if (typeof len === 'number' && len > 0) {
        var _size = Math.ceil(this.length / len), _offset = 0;
        _ret = new Array(_size);
        for (var _i = 0; _i < _size; _i++) {
            _ret[_i] = this.substring(_offset, _offset = _offset + len);
        }
    }
    else if (typeof len === 'object' && len.length) {
        var n = 0, l = this.length, chunk, that = this;
        _ret = [];
        do {
            len.forEach(function(o) {
                chunk = that.substring(n, n + o);
                if (chunk !== '') {
                    _ret.push(chunk);
                    n += chunk.length;
                }
            });
            if (n === 0) {
                return undefined; // prevent an endless loop when len = [0]
            }
        } while (n < l);
    }
    return _ret;
};

Код

"1234567890123".chunkString([1,3])

вернется:

[ '1', '234', '5', '678', '9', '012', '3' ]
2 голосов
/ 15 февраля 2017

это разделить большую строку на Маленькие строки заданных слов .

function chunkSubstr(str, words) {
  var parts = str.split(" ") , values = [] , i = 0 , tmpVar = "";
  $.each(parts, function(index, value) {
      if(tmpVar.length < words){
          tmpVar += " " + value;
      }else{
          values[i] = tmpVar.replace(/\s+/g, " ");
          i++;
          tmpVar = value;
      }
  });
  if(values.length < 1 &&  parts.length > 0){
      values[0] = tmpVar;
  }
  return values;
}
1 голос
/ 21 октября 2011
var l = str.length, lc = 0, chunks = [], c = 0, chunkSize = 2;
for (; lc < l; c++) {
  chunks[c] = str.slice(lc, lc += chunkSize);
}
1 голос
/ 12 апреля 2012

Я бы использовал регулярное выражение ...

var chunkStr = function(str, chunkLength) {
    return str.match(new RegExp('[\\s\\S]{1,' + +chunkLength + '}', 'g'));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...