I am trying to extract a string value, but I need a generic code to extract the values.
INPUT 1 : "/rack=1/shelf=1/slot=12/port=200"
INPUT 2 : "/shelf=1/slot=13/port=3"
INPUT 3 : "/shelf=1/slot=142/subslot=2/port=4"
I need the below output:
OUTPUT 1 : "/rack=1/shelf=1/slot=12"
OUTPUT 2 : "/shelf=1/slot=13"
OUTPUT 3 : "/shelf=1/slot=142"
Basically I am trying to extract up to the slot value. I tried indexOf and substr, but those are specific to individual string values. I require a generic code to extract up to slot. Is there a way how I can match the numeric after the slot and perform extraction?
We can try matching on the following regular expression, which captures all content we want to appear in the output:
^(.*\/shelf=\d+\/slot=\d+).*$
Note that this greedily captures all content up to, and including, the /shelf followed by /slot portions of the input path.
var inputs = ["/rack=1/shelf=1/slot=12/port=200", "/shelf=1/slot=13/port=3", "/shelf=1/slot=142/subslot=2/port=4"];
for (var i=0; i < inputs.length; ++i) {
var output = inputs[i].replace(/^(.*\/shelf=\d+\/slot=\d+).*$/, "$1");
console.log(inputs[i] + " => " + output);
}
You could use this function. If "subslot" is always after "slot" then you can remove the "/" in indexOf("/slot")
function exractUptoSlot(str) {
return str.substring(0,str.indexOf("/",str.indexOf("/slot")));
}
If it will always be the last substring, you could use slice:
function removeLastSubStr(str, delimiter) {
const splitStr = str.split(delimiter);
return splitStr
.slice(0, splitStr.length - 1)
.join(delimiter);
}
const str = "/rack=1/shelf=1/slot=12/port=200";
console.log(
removeLastSubStr(str, '/')
)
if you don't know where your substring is, but you know what it is you could filter it out of the split array:
function removeSubStr(str, delimiter, substr) {
const splitStr = str.split(delimiter);
return splitStr
.filter(s => !s.contains(substr))
.join(delimiter);
}
const str = "/rack=1/shelf=1/slot=12/port=200";
console.log(
removeSubStr(str, '/', 'port=200')
)
console.log(
removeSubStr(str, '/', 'port')
)
Related
I was taking on a JS challenge to take a first/last name string input and do the following:
swap the first letter of first/last name
convert all characters to lowercase, except for the first characters, which need to be uppercase
Example:
input: DonAlD tRuMp
output: Tonald Drump
The following is the code I came up with:
const input = prompt("Enter a name:")
function switchFirstLetters(input) {
let stringArray = input.split('');
for(let i=0; i < stringArray.length; i++) {
if(stringArray[i - 1] === ' ') {
[stringArray[0], stringArray[i]] = [stringArray[i], stringArray[0]]; // destructuring
}
}
return result = stringArray.join('');
}
let swappedString = switchFirstLetters(input);
function capFirstLetters(swappedString) {
let stringArray = swappedString.toLowerCase();
stringArray = stringArray.split('');
stringArray[0] = stringArray[0].toUpperCase();
for(let i=0; i < stringArray.length; i++) {
if(stringArray[i - 1] === ' ') {
stringArray[i] = stringArray[i].toUpperCase();
}
}
return result = stringArray.join('');
}
let finalString = capFirstLetters(swappedString);
console.log(finalString);
My thought process for the switchFirstLetters function was:
Create an array from the string parameter
Run through the array length. If the value of the element prior the current element is equal to ' ', use destructuring to swap the current element with the element at index 0
Concatenate elements into a new string and return that value
My thought process for the capFirstLetters function:
Convert all characters in the string to lowercase (this could be handled outside of the function as well)
Create an array from the new, lowercase string
Make character at index 0 be uppercase (this could also be integrated into the for loop)
Run through the array length. If the value of the element prior to the current element is equal to ' ', convert that element to uppercase.
Concatenate array elements into a new string
The code works, but I'm still early in my coding journey and realize it's likely not an ideal solution, so I was wondering if anyone here could help me optimize this further to help me learn. Thanks!
You could also use a regular expression to replace the first letters:
let name = "DonAlD tRuMp";
let result = name.toLowerCase().replace(/(\S)(\S*\s+)(\S)/g, (_, a, b, c) =>
c.toUpperCase() + b + a.toUpperCase()
);
console.log(result);
The regular expression uses \S (a non-white-space character), \S* (zero or more of those), \s+ (one or more white-space characters) and parentheses to create capture groups. These three groups map to a,b,c parameters in the callback function that is passed to replace as second argument. With these parts the replacement string can be constructed. Both the capitalisation and the switch happen in the construction.
If the replace function is a little overwhelming, my attempt introduces the for-of loop, the substring string method, array slice as well as the && short circuit evaluation. You should also be aware you can access a given character of a string using the square bracket syntax, just like array, but string has it's own set of methods which tend to have different names.
Definitely take a look at the replace function, to make your v2.
const rawNameInput = "DonAlD jUnior tRuMp"
const nameInput = rawNameInput.trim()
const rawNameWords = nameInput.split(" ")
const nameWords = []
for (const word of rawNameWords) {
const first = word[0].toUpperCase()
const rest = word.substring(1).toLowerCase()
nameWords.push(first + rest)
}
const middleNames = nameWords.slice(1, -1).join(" ")
const lastIdx = nameWords.length - 1
const newFirstName = nameWords[lastIdx][0] + nameWords[0].substring(1)
const newLastName = nameWords[0][0] + nameWords[lastIdx].substring(1)
console.log(`${newFirstName} ${middleNames && middleNames + " "}${newLastName}`)
I have a string that I need to split by a certain delimiter and convert into an array, but without removing the delimiter itself.
For example, consider the following code:
var str = "#mavic#phantom#spark";
str.split("#") //["", "mavic", "phantom", "spark"]
I need the output to be as follows:
["#mavic", "#phantom", "#spark"]
I read here but that does not answer my question.
You could split by positive lookahead of #.
var string = "#mavic#phantom#spark",
splitted = string.split(/(?=#)/);
console.log(splitted);
Split the string by # and use the reduce to return the modified string
var str = "#mavic#phantom#spark";
let x = str.split("#").reduce((acc, curr) => {
if (curr !== '') {
acc.push('#' + curr);
}
return acc;
}, [])
console.log(x)
Here is also some non-regexp methods of solving your task:
Solution 1 classical approach - iterate over the string and each time when we find indexOf our delimiter, we push to the result array the substring between current position and the next position. In the else block we have a case for the last substring - we simply add it to the result array and break the loop.
const delimiter = '#';
const result1 = [];
let i = 0;
while (i < str.length) {
const nextPosition = str.indexOf(delimiter, i+1);
if (nextPosition > 0) {
result1.push(str.substring(i, nextPosition));
i = nextPosition;
} else {
result1.push(str.substring(i));
break;
}
}
Solution 2 - split the initial string starting at index 1 (in order to not include empty string in the result array) and then just map the result array by concatenating the delimiter and current array item.
const result2 = str.substr(1).split(delimiter).map(s => delimiter + s);
another way:
filter empty elements after splitting, and map these elements to start with the character you splitted with.
string.split("#").filter((elem) => elem).map((elem) => "#" + elem);
Hey I want a function that can split a string for example "(12/x+3)*heyo" which i could edit each number, letter and word by itself and then return the edited version. So far i got this (which not work as intended):
function calculate(input){
var vars = input.split(/[+-/*()]/);
var operations = input.split(/[^+-/*()]/);
var output = "";
vars = vars.map(x=>{
return x+"1";
});
for(var i=0; i<operations.length; i++){
output += operations[i]+""+((vars[i])?vars[i]:"");
}
return output;
}
For example: (12/x+3)*heyo returns: (1121/x1+31)*1heyo1 but should return (121/x1+31)*heyo1
You can use regex and replace method for this task:
var s = "(12/x+3)*heyo";
console.log(
s.replace(/([a-zA-Z0-9]+)/g, "$1" + 1)
)
Depending what characters you want to match, you may want /([^-+/*()]+)/g as the pattern:
var s = "(12/x+3)*heyo";
console.log(
s.replace(/([^-+/*()]+)/g, "$1" + 1)
)
It looks like the vars array is populated with empty results, which are adding "1" inadvertently. I slightly modified your arrow function to check x for a value.
vars = vars.map(x=>{
if (x) {
return x+"1";
}
});
It can be simplified a bit (but \w matches underscore too [a-zA-Z0-9_]) :
console.log( '(12/x+3)*heyo'.replace(/\w+/g, '$&1') )
console.log( '(12/x+3)*heyo'.replace(/\w+/g, m => m + 1) )
I am still rather new to JavaScript and I am having an issue of getting the first character of the string inside the array to become uppercase.
I have gotten to a point where I have gotten all the texted lowercase, reversed the text character by character, and made it into a string. I need to get the first letter in the string to uppercase now.
function yay () {
var input = "Party like its 2015";
return input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
input[i] = input[i].charAt(0).toUpperCase() + input[i].substr(1);
}
}
console.log(yay());
I need the output to be "partY likE itS 2015"
Frustrating that you posted your initial question without disclosing the desired result. Lots of turmoil because of that. Now, that the desired result is finally clear - here's an answer.
You can lowercase the whole thing, then split into words, rebuild each word in the array by uppercasing the last character in the word, then rejoin the array:
function endCaseWords(input) {
return input.toLowerCase().split(" ").map(function(item) {
return item.slice(0, -1) + item.slice(-1).toUpperCase();
}).join(" ");
}
document.write(endCaseWords("Party like its 2015"));
Here's a step by step explanation:
Lowercase the whole string
Use .split(" ") to split into an array of words
Use .map() to iterate the array
For each word, create a new word that is the first part of the word added to an uppercased version of the last character in the word
.join(" ") back together into a single string
Return the result
You could also use a regex replace with a custom callback:
function endCaseWords(input) {
return input.toLowerCase().replace(/.\b/g, function(match) {
return match.toUpperCase();
});
}
document.write(endCaseWords("Party like its 2015"));
FYI, there are lots of things wrong with your original code. The biggest mistake is that as soon as you return in a function, no other code in that function is executed so your for loop was never executed.
Then, there's really no reason to need to reverse() the characters because once you split into words, you can just access the last character in each word.
Instead of returning the result splitting and reversing the string, you need to assign it to input. Otherwise, you return from the function before doing the loop that capitalizes the words.
Then after the for loop you should return the joined string.
Also, since you've reverse the string before you capitalize, you should be capitalizing the last letter of each word. Then you need to reverse the array before re-joining it, to get the words back in the original order.
function yay () {
var input = "Party like its 2015";
input = input.toLowerCase().split("").reverse().join("").split(" ");
for(var i = 1 ; i < input.length ; i++){
var len = input[i].length-1;
input[i] = input[i].substring(0, len) + input[i].substr(len).toUpperCase();
}
return input.reverse().join(" ");
}
alert(yay());
You can use regular expression for that:
input.toLowerCase().replace(/[a-z]\b/g, function (c) { return c.toUpperCase() });
Or, if you can use arrow functions, simply:
input.toLowerCase().replace(/[a-z]\b/g, c => c.toUpperCase())
Here's what I would do:
Split the sentence on the space character
Transform the resulting array using .map to capitalize the first character and lowercase the remaining ones
Join the array on a space again to get a string
function yay () {
var input = "Party like its 2015";
return input.split(" ").map(function(item) {
return item.charAt(0).toUpperCase() + item.slice(1).toLowerCase();
}).join(" ");
}
console.log(yay());
Some ugly, but working code:
var text = "Party like its 2015";
//partY likE itS 2015
function yay(input) {
input = input.split(' ');
arr = [];
for (i = 0; i < input.length; i++) {
new_inp = input[i].charAt(0).toLowerCase() + input[i].substring(1, input[i].length - 1) + input[i].charAt(input[i].length - 1).toUpperCase();
arr.push(new_inp);
}
str = arr.join(' ');
return str;
}
console.log(yay(text));
Try using ucwords from PHP.js. It's quite simple, actually.
String.prototype.ucwords = function() {
return (this + '')
.replace(/^([a-z\u00E0-\u00FC])|\s+([a-z\u00E0-\u00FC])/g, function($1) {
return $1.toUpperCase();
});
}
var input = "Party like its 2015";
input = input.charAt(0).toLowerCase() + input.substr(1);
input = input.split('').reverse().join('').ucwords();
input = input.split('').reverse().join('');
Note: I modified their function to be a String function so method chaining would work.
function yay(str)
{
let arr = str.split(' ');
let farr = arr.map((item) =>{
let x = item.split('');
let len = x.length-1
x[len] = x[len].toUpperCase();
x= x.join('')
return x;
})
return farr.join(' ')
}
var str = "Party like its 2015";
let output = yay(str);
console.log(output) /// "PartY likE itS 2015"
You can split and then map over the array perform uppercase logic and retun by joining string.
let string = "Party like its 2015";
const yay = (string) => {
let lastCharUpperCase = string.split(" ").map((elem) => {
elem = elem.toLowerCase();
return elem.replace(elem[elem.length - 1], elem[elem.length - 1].toUpperCase())
})
return lastCharUpperCase.join(" ");
}
console.log(yay(string))
I have a dynamically formed string like - part1.abc.part2.abc.part3.abc whose length is unknown
In this string I want to get the substring based on second occurrence of "." so that I can get and part1.abc part2.abc part3.abc.
And if the string is like - part1.abc.part2.abc.part3.abc.part4 output must be like part1.abc part2.abc part3.abc part4
How to get this?
Something like this :
str="part1.abc.part2.abc.part3.abc.part4"
temp=str.split('.');
out=[]
for(i=0; i<temp.length;i=i+2)
out.push(temp.slice(i,i+2).join('.'));
//["part1.abc", "part2.abc", "part3.abc", "part4"]
As suggested in my comment, the simplest (and fastest) way is to use a regular expression and match:
// ['part1.abc', 'part2.abc', 'part3.abc', 'part4']
'part1.abc.part2.abc.part3.abc.part4'.match(/[^.]+(\.[^.]+)?/g);
Simple function which allows you to specify the number of items to join together and delimiter which you can use to join them.
var concatBy = function(list, delimiter, by) {
var result = [];
for (var i = 0; i < list.length; i += by) {
result.push(list.slice(i, i + by).join(delimiter))
}
return result;
}
concatBy('part1.abc.part2.abc.part3.abc'.split('.'), '.', 2) // returns concatBy('part1.abc.part2.abc.part3.abc.part4'.split('.'), '.', 2)
concatBy('part1.abc.part2.abc.part3.abc.part4'.split('.'), '.', 2) // returns ["part1.abc", "part2.abc", "part3.abc", "part4"]