Split a JavaScript string into fixed-length pieces - javascript

I would like to split a string into fixed-length (N, for example) pieces. Of course, last piece could be shorter, if original string's length is not multiple of N.
I need the fastest method to do it, but also the simplest to write. The way I have been doing it until now is the following:
var a = 'aaaabbbbccccee';
var b = [];
for(var i = 4; i < a.length; i += 4){ // length 4, for example
b.push(a.slice(i-4, i));
}
b.push(a.slice(a.length - (4 - a.length % 4))); // last fragment
I think there must be a better way to do what I want. But I don't want extra modules or libraries, just simple JavaScript if it's possible.
Before ask, I have seen some solutions to resolve this problem using other languages, but they are not designed with JavaScript in mind.

You can try this:
var a = 'aaaabbbbccccee';
var b = a.match(/(.{1,4})/g);

See this related question: https://stackoverflow.com/a/10456644/711085 and https://stackoverflow.com/a/8495740/711085 (See performance test in comments if performance is an issue.)
First (slower) link:
[].concat.apply([],
a.split('').map(function(x,i){ return i%4 ? [] : a.slice(i,i+4) })
)
As a string prototype:
String.prototype.chunk = function(size) {
return [].concat.apply([],
this.split('').map(function(x,i){ return i%size ? [] : this.slice(i,i+size) }, this)
)
}
Demo:
> '123412341234123412'.chunk(4)
["1234", "1234", "1234", "1234", "12"]

function stringToChanks(string, chunkSize) {
const chunks = [];
while (string.length > 0) {
chunks.push(string.substring(0, chunkSize));
string = string.substring(chunkSize, string.length);
}
return chunks
}

Related

One line Array iterator javascript

I am coming from Python and I am looking for a single line iterator function for any array, where I can also check a condition and return a simple change to the items.
Expected result should match the method:
function arrayEvenItemIncrement(myArray){
for (let i = 0; i < myArray.length; i++){
if (myArray[i]%2==0){
myArray[i]++;
}
}
return myArray;
}
I tried using for (i of myArray){ } but this still doesn't serve my purpose.
I think the clearest way to do what you want here would be to map to a new array instead of mutating the old one:
const arrayEvenItemIncrement = myArray =>
myArray.map((val, i) => i % 2 === 1 ? val : val + 1);
If you have to mutate the existing array, it gets significantly uglier.
const arrayEvenItemIncrement = myArray => (
myArray.forEach((val, i) => { if (i % 2 === 0) myArray[i]++; }), myArray);
or
const arrayEvenItemIncrement = myArray => {
myArray.forEach((val, i) => { if (i % 2 === 0) myArray[i]++; }); return myArray };
But I wouldn't recommend that - put it on multiple lines instead.
You can technically squeeze any JS code into a single line, but past simple manipulations, it usually isn't a good idea because it sacrifices readability, which is far more important than reducing LoC. Professional, maintainable code is not a golfing competition.
Thank you for the answers.
I have settled for this:
myArray.forEach(el=>el%2===0?newArray.push(el):null);

How do write a function that takes in 2 strings and return an array of common characters (should not contain any duplicates)?

I have tried the codes below. However, I do not know how to remove the duplicate characters.
Please do help me in the thought process of how to remove the duplicate characters. Thank you! (JavaScript beginner here)
function get_common_characters(str1, str2) {
let common_chars = []
// YOUR CODE GOES HERE
new_str1 = str1.replace(" ", "").toLowerCase()
// console.log(new_str1)
new_str2 = str2.replace(" ", "").toLowerCase()
for (let i=0; i < new_str1.length; i++){
for (let j=0; j < new_str2.length; j++){
if (new_str1[i] == new_str2[i]){
common_chars.push(new_str1[i])
}
}
}
return common_chars
}
The below image is the output of the test cases in the console.
These are the test cases for the above codes.
function get_common_characters(str1, str2) {
const set1 = new Set(str1.split(''))
const set2 = new Set(str2.split(''))
const result = []
for(let char of set1.values()){
if(set2.has(char)) result.push(char)
}
return result
}
While you could deduplicate the common_chars afterwards
return [...new Set(common_chars)]
I think a nicer looking (and less computationally complex) approach would be to make Sets of both strings ahead of time, then iterate through one of them while checking to see if the other contains the character in question.
function get_common_characters(str1, str2) {
const set1 = new Set(str1);
return [...new Set(str2)]
.filter(char => set1.has(char));
}

Is there a faster Reverse String Algorithm for JavaScript?

So I'm looking for the fastest possible Reverse String function.
Here are my function and all the functions that I found on the internet and their perfromance tests:
https://jsperf.com/javascript-reversing-string-performance
It looks like the fastest one (and the prettiest in my opinion) is this:
function reverseString(str) {
return str.split().reverse().join("");
}
But maybe there is even more efficient, faster way to do this?
There are potentially tens of different ways to do it, excluding the built-in reverse function, as JavaScript does not have one.
Below are my three most interesting ways to solve the problem of reversing a string in JavaScript.
Solution 1
function reverseString (str) {
return str.split('').reverse().join('')
}
console.time("function test");
reverseString('Hello') // => 0.250ms
console.timeEnd("function test");
Solution 2
function reverseString (str) {
let reversed = '';
for (const character of str) {
reversed = character + reversed
}
return reversed
}
console.time("function test");
reverseString('Hello') // => 0.166ms
console.timeEnd("function test");
Solution 3
function reverseString (str) {
return str.split('').reduce((reversed, character) => character + reversed, '')
}
console.time("function test");
reverseString('Hello') // => 0.133ms
console.timeEnd("function test");
In ES6, you have one more option
function reverseString (str) {
return [...str].reverse().join('')
}
This one seems to be even faster:
function reverseString(str) {
let reversed = "";
const l = str.length;
for(let i = l-1; i >= 0; i--) {
reversed = `${reversed}${str[i]}`;
}
return reversed;
}
Based on davaakhuu-erdenekhuu solutions I've created a benchmark so you can test which is the best for you
https://jsbench.me/4bkfflcm2z
I've run it on Firefox and Chrome on a Macbook pro 16
Seems like the 1st option was the fastest on Firefox and the 3rd options was the fastest on Chrome
Hope you find it useful
function reverseString(str) {
let reversed = ""
for (let i = str.length -1; i >= 0; i--){
reversed = reversed + str[i]
}
return reversed;
}
Working from the end of the input string is optimal, especially depending on how you go about combining the characters. Remember that when you modify arrays by inserting (or removing) elements at the beginning, all other elements must have their index adjusted.
For any ArrayLike type, the fastest way to reverse is logically, by wrapping it into a reversed iterable:
function reverse<T>(input: ArrayLike<T>): Iterable<T> {
return {
[Symbol.iterator](): Iterator<T> {
let i = input.length;
return {
next(): IteratorResult<T> {
return i
? {value: input[--i], done: false}
: {value: undefined, done: true};
},
};
},
};
}
Now you can reverse-iterate through any array, string or buffer, without any extra copy or processing for the reversed data:
for(const a of reverse([1, 2, 3])) {
console.log(a); //=> 3 2 1
}
It is the fastest approach, because you do not copy the data, and do no processing at all, you just reverse it logically.
I tested my method in Firefox and Chrome and it was the fastest method among the methods given here. I just use simple for loop
function reverseString5(str) {
let x = '';
for (let i = str.length - 1; i >= 0; --i) {
x += str[i];
}
return x;
}
All tests were run here

Determining whether an array contains duplicate values

I would like to scan through a JS array and determine if all the elements are unique, or whether the array contains duplicates.
example :
my_array1 = [1, 2, 3]
my_array2 = [1, 1, 1]
I want get result like this :
my_array1 must be return true, because this array element is unique
and array2 must be return false, because this array element is not unique
How can I go about writing this method?
Sort your array first of all, and then go for a simple comparison loop.
function checkIfArrayIsUnique(arr) {
var myArray = arr.sort();
for (var i = 0; i < myArray.length; i++) {
if (myArray.indexOf(myArray[i]) !== myArray.lastIndexOf(myArray[i])) {
return false;
}
}
return true;
}
if you want to check for uniqueness you can also do this.As stated on the comment i do not assert this is as the only best option.There are some great answers down below.
var arr = [2,3,4,6,7,8,9];
var uniq = []; // we will use this to store the unique numbers found
// in the process for doing the comparison
var result = arr.slice(0).every(function(item, index, array){
if(uniq.indexOf(item) > -1){
// short circuit the loop
array.length=0; //(B)
return false;
}else{
uniq.push(item);
return true;
}
});
result --> true
arr.slice(0) creates a temporary copy of the array, on which the actual processing is done.This is because when the uniqueness criteria is met i clear the array (B) to short circuit the loop.This will make sure the processing stops as soon as the criteria is met.
And will be more nicer if we expose this as a method on a Array instance.
so we can do something like this [1,2,3,5,7].isUnique();
Add the following snippet and you are ready to go
Array.prototype.isUnique = function() {
var uniq = [];
var result = this.slice(0).every(function(item, index, arr) {
if (uniq.indexOf(item) > -1) {
arr.length = 0;
return false;
} else {
uniq.push(item);
return true;
}
});
return result;
};
arr.isUnique() --> true
DEMO
You may try like this:
function uniqueArray(arr) {
var hash = {}, result = [];
for ( var i = 0, l = arr.length; i < l; ++i ) {
if ( !hash.hasOwnProperty(arr[i]) ) {
hash[ arr[i] ] = true;
result.push(arr[i]);
}
}
return result;
}
try this :-
var my_array1 = [1, 2, 3]
var my_array2 = [1, 1, 1]
function isUnique(obj)
{
var unique=obj.filter(function(itm,i,a){
return i==a.indexOf(itm);
});
return unique.length == obj.length;
}
alert(isUnique(my_array1))
alert(isUnique(my_array2))
Demo
I think you can try with Underscore js , a powerful javascript library
Example the way to use underscore
function checkUniqueArr(arr){
var unique_arr = _.uniq(arr);
return arr.length == unique_arr.length;
}
The most efficient way to test uniqueness is:
function isUnique(arr) {
for(var i = 0; i < arr.length; i++) {
if (arr.indexOf(arr[i]) != i) return false;
}
return true;
}
This is O(n2) at worst case. At most time, it doesn't need to finish scanning for not-unique array.
function containsDuplicates(arr) {
var seen = {};
var duplicate = false;
for (var i = 0; i < arr.length; i++) {
if (seen[arr[i]]) {
duplicate = true;
break;
}
seen[arr[i]] = true;
}
return duplicate;
}
jsFiddle
Best-case: O(1) time and space - second element is the duplicate
Average/worst-case: O(n) time and space - no duplicates, or the duplicate is in the middle
Many of the answers here seem to be relying on some complex interspersion of array methods, which are inherently iterative, and generally don't seem appropriate for this fairly simple task. Algorithmically, this problem can be solved in O(n) time, but any nesting of indexOf/filter/map (or similar array methods) in a for loop means that your computation time will grow (at best) quadratically with your array size, rather than linearly. This is inefficient in time.
Now, in general, micro-optimization really is not necessary unless you have identified this to be a performance bottleneck in your application. But this kind of algorithm, in my opinion, is something you design (in pseudocode) and match to your application's needs before you even start coding. If you will have a huge data-set in your array, you will probably appreciate not having to look through it several times to get your answer. Of course, the caveat here is that you're trading time complexity for space complexity, since my solution requires O(n) space for caching previously seen values.
If you need to check all element are unique then following will do the trick
<script>
my_array1 = [11, 20, 3]
my_array2 = [11, 11, 11]
var sorted1= my_array1.sort();
var sorted2= my_array2.sort();
if(sorted1[0]==sorted1[sorted1.length-1])
alert('all same');
if(sorted2[0]==sorted2[sorted2.length-1])
alert('all same');
</script>
I just came up with this answer.
I'm preparing for an interview.
I think this is rock solid.
let r = [1,9,2,3,8];
let r2 = [9,3,6,3,8];
let isThereDuplicates= r.slice().sort().some((item,index,ar)=>(item ===ar[index+1]));
console.log('r is: ',isThereDuplicates) // -> false. All numbers are unique
isThereDuplicates= r2.slice().sort().some((item,index,ar)=>(item ===ar[index+1]));
console.log('r2 is: ',isThereDuplicates) //->true. 3 is duplicated
I first slice and sort without mutating the original array.
r.slice().sort()
Then I check that for at least one item, item is equal to the next item on the array.
.some((item,index,array)=>
item === array[index+1]
);

How to check if a string contains text from an array of substrings in JavaScript?

Pretty straight forward. In javascript, I need to check if a string contains any substrings held in an array.
There's nothing built-in that will do that for you, you'll have to write a function for it, although it can be just a callback to the some array method.
Two approaches for you:
Array some method
Regular expression
Array some
The array some method (added in ES5) makes this quite straightforward:
if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
// There's at least one
}
Even better with an arrow function and the newish includes method (both ES2015+):
if (substrings.some(v => str.includes(v))) {
// There's at least one
}
Live Example:
const substrings = ["one", "two", "three"];
let str;
// Setup
console.log(`Substrings: ${substrings}`);
// Try it where we expect a match
str = "this has one";
if (substrings.some(v => str.includes(v))) {
console.log(`Match using "${str}"`);
} else {
console.log(`No match using "${str}"`);
}
// Try it where we DON'T expect a match
str = "this doesn't have any";
if (substrings.some(v => str.includes(v))) {
console.log(`Match using "${str}"`);
} else {
console.log(`No match using "${str}"`);
}
Regular expression
If you know the strings don't contain any of the characters that are special in regular expressions, then you can cheat a bit, like this:
if (new RegExp(substrings.join("|")).test(string)) {
// At least one match
}
...which creates a regular expression that's a series of alternations for the substrings you're looking for (e.g., one|two) and tests to see if there are matches for any of them, but if any of the substrings contains any characters that are special in regexes (*, [, etc.), you'd have to escape them first and you're better off just doing the boring loop instead. For info about escaping them, see this question's answers.
Live Example:
const substrings = ["one", "two", "three"];
let str;
// Setup
console.log(`Substrings: ${substrings}`);
// Try it where we expect a match
str = "this has one";
if (new RegExp(substrings.join("|")).test(str)) {
console.log(`Match using "${str}"`);
} else {
console.log(`No match using "${str}"`);
}
// Try it where we DON'T expect a match
str = "this doesn't have any";
if (new RegExp(substrings.join("|")).test(str)) {
console.log(`Match using "${str}"`);
} else {
console.log(`No match using "${str}"`);
}
One line solution
substringsArray.some(substring=>yourBigString.includes(substring))
Returns true\false if substring exists\does'nt exist
Needs ES6 support
var yourstring = 'tasty food'; // the string to check against
var substrings = ['foo','bar'],
length = substrings.length;
while(length--) {
if (yourstring.indexOf(substrings[length])!=-1) {
// one of the substrings is in yourstring
}
}
function containsAny(str, substrings) {
for (var i = 0; i != substrings.length; i++) {
var substring = substrings[i];
if (str.indexOf(substring) != - 1) {
return substring;
}
}
return null;
}
var result = containsAny("defg", ["ab", "cd", "ef"]);
console.log("String was found in substring " + result);
For people Googling,
The solid answer should be.
const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
// Will only return when the `str` is included in the `substrings`
}
Here's what is (IMO) by far the best solution. It's a modern (ES6) solution that:
is efficient (one line!)
avoids for loops
unlike the some() function that's used in the other answers, this one doesn't just return a boolean (true/false)
instead, it either returns the substring (if it was found in the array), or returns undefined
goes a step further and allows you to choose whether or not you need partial substring matches (examples below)
Enjoy!
const arrayOfStrings = ['abc', 'def', 'xyz'];
const str = 'abc';
const found = arrayOfStrings.find(v => (str === v));
Here, found would be set to 'abc' in this case. This will work for exact string matches.
If instead you use:
const found = arrayOfStrings.find(v => str.includes(v));
Once again, found would be set to 'abc' in this case. This doesn't allow for partial matches, so if str was set to 'ab', found would be undefined.
And, if you want partial matches to work, simply flip it so you're doing:
const found = arrayOfStrings.find(v => v.includes(str));
instead. So if str was set to 'ab', found would be set to 'abc'.
Easy peasy!
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = 0, len = arr.length; i < len; ++i) {
if (str.indexOf(arr[i]) != -1) {
// str contains arr[i]
}
}
edit:
If the order of the tests doesn't matter, you could use this (with only one loop variable):
var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = arr.length - 1; i >= 0; --i) {
if (str.indexOf(arr[i]) != -1) {
// str contains arr[i]
}
}
substringsArray.every(substring=>yourBigString.indexOf(substring) === -1)
For full support ;)
For full support (additionally to #ricca 's verions).
wordsArray = ['hello', 'to', 'nice', 'day']
yourString = 'Hello. Today is a nice day'.toLowerCase()
result = wordsArray.every(w => yourString.includes(w))
console.log('result:', result)
If the array is not large, you could just loop and check the string against each substring individually using indexOf(). Alternatively you could construct a regular expression with substrings as alternatives, which may or may not be more efficient.
Javascript function to search an array of tags or keywords using a search string or an array of search strings. (Uses ES5 some array method and ES6 arrow functions)
// returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
function contains(a, b) {
// array matches
if (Array.isArray(b)) {
return b.some(x => a.indexOf(x) > -1);
}
// string match
return a.indexOf(b) > -1;
}
Example usage:
var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
// 1 or more matches found
}
This is super late, but I just ran into this problem. In my own project I used the following to check if a string was in an array:
["a","b"].includes('a') // true
["a","b"].includes('b') // true
["a","b"].includes('c') // false
This way you can take a predefined array and check if it contains a string:
var parameters = ['a','b']
parameters.includes('a') // true
Best answer is here:
This is case insensitive as well
var specsFilter = [.....];
var yourString = "......";
//if found a match
if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
// do something
}
const str = 'Does this string have one or more strings from the array below?';
const arr = ['one', 'two', 'three'];
const contains = arr.some(element => {
if (str.includes(element)) {
return true;
}
return false;
});
console.log(contains); // true
Not that I'm suggesting that you go and extend/modify String's prototype, but this is what I've done:
String.prototype.includes()
String.prototype.includes = function (includes) {
console.warn("String.prototype.includes() has been modified.");
return function (searchString, position) {
if (searchString instanceof Array) {
for (var i = 0; i < searchString.length; i++) {
if (includes.call(this, searchString[i], position)) {
return true;
}
}
return false;
} else {
return includes.call(this, searchString, position);
}
}
}(String.prototype.includes);
console.log('"Hello, World!".includes("foo");', "Hello, World!".includes("foo") ); // false
console.log('"Hello, World!".includes(",");', "Hello, World!".includes(",") ); // true
console.log('"Hello, World!".includes(["foo", ","])', "Hello, World!".includes(["foo", ","]) ); // true
console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false
building on T.J Crowder's answer
using escaped RegExp to test for "at least once" occurrence, of at least one of the substrings.
function buildSearch(substrings) {
return new RegExp(
substrings
.map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
.join('{1,}|') + '{1,}'
);
}
var pattern = buildSearch(['hello','world']);
console.log(pattern.test('hello there'));
console.log(pattern.test('what a wonderful world'));
console.log(pattern.test('my name is ...'));
Drawing from T.J. Crowder's solution, I created a prototype to deal with this problem:
Array.prototype.check = function (s) {
return this.some((v) => {
return s.indexOf(v) >= 0;
});
};
Using underscore.js or lodash.js, you can do the following on an array of strings:
var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];
var filters = ['Bill', 'Sarah'];
contacts = _.filter(contacts, function(contact) {
return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
});
// ['John']
And on a single string:
var contact = 'Billy';
var filters = ['Bill', 'Sarah'];
_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });
// true
If you're working with a long list of substrings consisting of full "words" separated by spaces or any other common character, you can be a little clever in your search.
First divide your string into groups of X, then X+1, then X+2, ..., up to Y. X and Y should be the number of words in your substring with the fewest and most words respectively. For example if X is 1 and Y is 4, "Alpha Beta Gamma Delta" becomes:
"Alpha" "Beta" "Gamma" "Delta"
"Alpha Beta" "Beta Gamma" "Gamma Delta"
"Alpha Beta Gamma" "Beta Gamma Delta"
"Alpha Beta Gamma Delta"
If X would be 2 and Y be 3, then you'd omit the first and last row.
Now you can search on this list quickly if you insert it into a Set (or a Map), much faster than by string comparison.
The downside is that you can't search for substrings like "ta Gamm". Of course you could allow for that by splitting by character instead of by word, but then you'd often need to build a massive Set and the time/memory spent doing so outweighs the benefits.
convert_to_array = function (sentence) {
return sentence.trim().split(" ");
};
let ages = convert_to_array ("I'm a programmer in javascript writing script");
function confirmEnding(string) {
let target = "ipt";
return (string.substr(-target.length) === target) ? true : false;
}
function mySearchResult() {
return ages.filter(confirmEnding);
}
mySearchResult();
you could check like this and return an array of the matched words using filter
I had a problem like this. I had a URL, I wanted to check if the link ends in an image format or other file format, having an array of images format. Here is what I did:
const imagesFormat = ['.jpg','.png','.svg']
const link = "https://res.cloudinary.com/***/content/file_padnar.pdf"
const isIncludes = imagesFormat.some(format => link.includes(format))
// false
You can check like this:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
var list = ["bad", "words", "include"]
var sentence = $("#comments_text").val()
$.each(list, function( index, value ) {
if (sentence.indexOf(value) > -1) {
console.log(value)
}
});
});
</script>
</head>
<body>
<input id="comments_text" value="This is a bad, with include test">
</body>
</html>
let obj = [{name : 'amit'},{name : 'arti'},{name : 'sumit'}];
let input = 'it';
Use filter :
obj.filter((n)=> n.name.trim().toLowerCase().includes(input.trim().toLowerCase()))
var str = "A for apple"
var subString = ["apple"]
console.log(str.includes(subString))

Categories