Reputation: 1838
I want to split a string into parts with a defined length. This means if I have a given string like "1234567890"
and want to split it in parts with length 3
then I expect the result ["123", "456", "789", "0"]
. To achive this I have found a solution here: https://stackoverflow.com/a/14349616/2577116
Now, I also want to split not starting at the beginning but at the end of the string. The expected result would be ["1", "234", "567", "890"]
.
Therefore I used and modified the solution above and came up with this:
function (str, len, reversed) {
//create array from string
var _parts = str.split(""),
_size = Math.ceil(_parts.length/len),
_ret = [],
_offset;
//should give ["123", "456", "789", "0"]
if (!reversed) {
for (var _i=0; _i<_size; _i++) {
_offset = _i * len;
_ret[_i] = _parts.slice(_offset, _offset+len).join("");
}
}
//should give ["1", "234", "567", "890"]
else {
//reverse input
_parts.reverse();
//apply same algorithm as above but don't join yet
for (var _j=0; _j<_size; _j++) {
_offset = _j * len;
_ret[_j] = _parts.slice(_offset, _offset+len);
}
//bring each subitem back to right order, join
_ret.forEach(function (item, i) {
_ret[i] = item.reverse().join("");
});
//reorder items
_ret.reverse();
}
return _ret;
}
This seems to work pretty well. I'm asking for some better/simplified solution as mine feels a little bulky.
Upvotes: 2
Views: 1474
Reputation: 87233
Try this:
Steps:
Code:
var str = '1234567890';
var rev = str.split('').reverse().join('');
var matches = rev.match(/([0-9]{1,3})/g).reverse().map(function(el) {
return el.split('').reverse().join('');
});
console.log(matches);
Even shorter(Less Redable)
var matches = '1234567890'.split('').reverse().join('').match(/([0-9]{1,3})/g).reverse().map(function(el) {
return el.split('').reverse().join('');
});
console.log(matches);
Upvotes: 1
Reputation: 1
This is what i made.
var string = '1234567890';
var chunks = 3;
console.log( sliceIt(string, chunks, true) );
console.log( sliceIt(string, chunks, false) );
function sliceIt( str , steps , rev ) {
var iterations = Math.ceil(str.length); // for the loop
var returnArray = [];
var strLen = str.length;
var modulo = strLen % steps; // for reverse purposes
// if modulo is 0 then no action needed. returns the modulo if both true
var firstStep = (rev === true) && (modulo != 0) ? modulo : false;
for (i=0; i < iterations;) {
// pushing to array
returnArray.push(str.substr( i , firstStep || steps ));
// increment the right way
i+= firstStep || steps;
// first step done.. deactivate
firstStep = false;
}
return returnArray;
}
Upvotes: 0
Reputation: 106
I would do something like this:
function foo(str,len,rev) {
var result = [];
if (rev && str.length%len != 0) {
result.push(str.substr(0, str.length % len));
str=str.substr(str.length % len);
}
for (var i=0; i<str.length; i+=len) {
result.push(str.substr(i,len));
}
return result;
}
The if statement will first check if reversed is true and if so it will calculate the rest when dividing the length of the string with the chunk size (check the modulo operation %). Then using the function "substr", that takes a starting position and a length, to get the first element of the list.
The for loop will iterate through the string "len" characters at the time and again using the function "substr" cut the string in to pieces of length "len" and add them to the list result.
Upvotes: 2
Reputation: 2671
If you prefer RegEx:
"1234567890".match(/(.{1,3})|(.{1,})/g)
Output:
["123", "456", "789", "0"]
For Reverse:
var splitLength = 3
var _str = "1234567890"
var startSubStringLength = _str.length % splitLength
_str.match(new RegExp("(^.{1," + startSubStringLength + "})|(.{1,3})|(.{1,})", "g"))
Output:
["1", "234", "567", "890"]
Complete Function
var _mySplit = function(str, splitLength, doReverse) {
var _regEx = new RegExp("(.{" + splitLength + "})|(.{1,})", "g");
if(doReverse) {
var startSubStringLength = str.length % splitLength
if(startSubStringLength > 0) {
_regEx = new RegExp("(^.{1," + startSubStringLength + "})|(.{1," + splitLength + "})|(.{1,})", "g")
}
}
return str.match(_regEx)
}
Output:
_mySplit("1234", 3, false)
["123", "4"]
_mySplit("1234", 3, true)
["1", "234"]
_mySplit("1234567890", 3, true)
["1", "234", "567", "890"]
_mySplit("1234567890", 3, false)
["123", "456", "789", "0"]
Upvotes: 1
Reputation: 3568
My solution :
function mySplit (str, len, reversed) {
//create array from string
var _parts = str.split(""),
_size = Math.ceil(_parts.length/len),
_ret = [],
_offset;
for (var _i=0; _i<_size; _i++) {
_offset = Math.abs((reversed ? _parts.length : 0 ) - (_i * len));
var sliceStart = reversed ? Math.max(0, _offset - len) : _offset;
var sliceEnd = reversed ? _offset : _offset + len;
_ret.push(_parts.slice(sliceStart, sliceEnd).join(""));
}
reversed && _ret.reverse();
return _ret;
}
var log = document.getElementById('log');
log.innerHTML += "string : 1234567890";
log.innerHTML += "\nreversed:" + mySplit("1234567890", 3, true)
log.innerHTML += "\nnot reversed:" + mySplit("1234567890", 3, false)
log.innerHTML += "\n\nstring : 123456789";
log.innerHTML += "\nreversed:" + mySplit("123456789", 3, true)
log.innerHTML += "\nnot reversed:" + mySplit("123456789", 3, false)
<pre id="log"></pre>
Upvotes: 0
Reputation: 5488
You can do this by rearranging the string and Using the same chunkString
function that you pointed at.
> chunkString(s.split('').reverse().join(''), 3).map(function(v){return v.split('').reverse().join('');}).reverse()
< ["1", "234", "567", "890"]
The split, reverse, join
are used to convert string to list, reverse, and then convert back to string.
Readeable code -
chunkString(
s.split('').reverse().join(''),
3
).map(
function(v){
return v.split('').reverse().join('');
}
).reverse()
Upvotes: 1