Javascript: nice human readable join of list - javascript

Having a list (array) of tags ['tag1', 'tag2', 'tag3'] I want to generate a nice title like: Content tagged tag1, tag2 and tag3.
For the moment I have:
"Content tagged " + tags_titles.join(" and ");
with the result:
Content tagged tag1 and tag2 and tag3
I know it's a simple question, but I am curious if there is a nice solution for this case.

You could get the two last elements and join them with ' and ' and put it as last element back into the array and later join all elements with ', ' for getting a nice string.
Methods
Array#concat, joins two arrays and returns a new array
Array#splice, for getting the last two elemensts of the array
Array#join, joins an array with the given spacer.
This proposal works for any length of an array, even with one or two elements.
function nice([...array]) {
return array.concat(array.splice(-2, 2).join(' and ')).join(', ');
}
console.log("Content tagged " + nice(['tag1']));
console.log("Content tagged " + nice(['tag1', 'tag2']));
console.log("Content tagged " + nice(['tag1', 'tag2', 'tag3']));

A bit of slicing and dicing using Array.prototype.slice:
function naturalLanguageJoin(arr){
if(!arr)
return '';
if(arr.length<2)
return (arr.length>0) ? arr[0] : '';
return arr.slice(0,arr.length-1).join(", ") + " and " + arr[arr.length-1];
}
console.log(naturalLanguageJoin(['tag1', 'tag2', 'tag3']));
console.log(naturalLanguageJoin(['tag1', 'tag2']));
console.log(naturalLanguageJoin(['tag1']));
console.log(naturalLanguageJoin([]));
console.log(naturalLanguageJoin(null));

An array can be treated as a stack so you can pop the last element and in turn write this
var last = tags_titles.pop();
last = tags_titles.length ? ` and ${last}` : last;
`Content tagged ${tags_titles.join(", ")} ${last}`
The code uses ES6 string templates, which I generally find to be more readable than doing string concatenation in the code. It also utilizes the fact that the pop method essentially performs to operations. Gets the lasst element of the array and mutate the array. That eliminate the need to do the mutation explicitly (using slice)

Try like this
var g = ['tag1', 'tag2', 'tag3'];
var title = g.slice(0, g.length-1).join(',').concat(' and ').concat(g[g.length-1]);

From my view, This is an simple approach
var tags = ['tag1', 'tag2', 'tag3'];
console.log("Content tagged " + tags.slice(0, -1).join(', ')+' and '+tags.slice(-1));
Hope it helps you :)
JsFiddle

Try this,
var arr = ['tag1', 'tag2', 'tag3'];
var lastStr = arr.pop();
var str = "Content tagged " + arr.join(", ") + " and " + lastStr;

Something like this would be my approach
function arrayFormat(arr) {
var output = arr.splice(0, arr.length - 1).join(", ");
output += " and " + arr[0];
return output;
}
console.log(arrayFormat(["a", "b", "c"]));

Related

Javascript join() and concat() one string [duplicate]

Having a list (array) of tags ['tag1', 'tag2', 'tag3'] I want to generate a nice title like: Content tagged tag1, tag2 and tag3.
For the moment I have:
"Content tagged " + tags_titles.join(" and ");
with the result:
Content tagged tag1 and tag2 and tag3
I know it's a simple question, but I am curious if there is a nice solution for this case.
You could get the two last elements and join them with ' and ' and put it as last element back into the array and later join all elements with ', ' for getting a nice string.
Methods
Array#concat, joins two arrays and returns a new array
Array#splice, for getting the last two elemensts of the array
Array#join, joins an array with the given spacer.
This proposal works for any length of an array, even with one or two elements.
function nice([...array]) {
return array.concat(array.splice(-2, 2).join(' and ')).join(', ');
}
console.log("Content tagged " + nice(['tag1']));
console.log("Content tagged " + nice(['tag1', 'tag2']));
console.log("Content tagged " + nice(['tag1', 'tag2', 'tag3']));
A bit of slicing and dicing using Array.prototype.slice:
function naturalLanguageJoin(arr){
if(!arr)
return '';
if(arr.length<2)
return (arr.length>0) ? arr[0] : '';
return arr.slice(0,arr.length-1).join(", ") + " and " + arr[arr.length-1];
}
console.log(naturalLanguageJoin(['tag1', 'tag2', 'tag3']));
console.log(naturalLanguageJoin(['tag1', 'tag2']));
console.log(naturalLanguageJoin(['tag1']));
console.log(naturalLanguageJoin([]));
console.log(naturalLanguageJoin(null));
An array can be treated as a stack so you can pop the last element and in turn write this
var last = tags_titles.pop();
last = tags_titles.length ? ` and ${last}` : last;
`Content tagged ${tags_titles.join(", ")} ${last}`
The code uses ES6 string templates, which I generally find to be more readable than doing string concatenation in the code. It also utilizes the fact that the pop method essentially performs to operations. Gets the lasst element of the array and mutate the array. That eliminate the need to do the mutation explicitly (using slice)
Try like this
var g = ['tag1', 'tag2', 'tag3'];
var title = g.slice(0, g.length-1).join(',').concat(' and ').concat(g[g.length-1]);
From my view, This is an simple approach
var tags = ['tag1', 'tag2', 'tag3'];
console.log("Content tagged " + tags.slice(0, -1).join(', ')+' and '+tags.slice(-1));
Hope it helps you :)
JsFiddle
Try this,
var arr = ['tag1', 'tag2', 'tag3'];
var lastStr = arr.pop();
var str = "Content tagged " + arr.join(", ") + " and " + lastStr;
Something like this would be my approach
function arrayFormat(arr) {
var output = arr.splice(0, arr.length - 1).join(", ");
output += " and " + arr[0];
return output;
}
console.log(arrayFormat(["a", "b", "c"]));

What the array().join() does in the following code?

var object = {
mastermind : "Brain",
henchman: "Pinky",
battleCry: function (noOfBrains) {
return "They are " + this.henchman + " and the" +
Array(noOfBrains + 1).join(" " + this.mastermind);
}
};
var battleCry = object.battleCry(4);
--
Can you explain why array().join() return:
Correct: "They are Pinky and the Brain Brain Brain Brain"
Incorrect: "They are Pinky and the 5 Brain"
The array().join() is used to join all the elements of an array together in one string. Optionally, you can specify a delimiter to separate the elements.
In your code, Array(noOfBrains + 1) creates a new array with the given length, in your example 4 + 1 = 5 items, but all those 5 items are empty because your code doesn't assign anything to them. So your code is joining 5 empty strings using " Brain" as delimiter. Essentially, this function is actually a repeater of any string assigned to the mastermind property for as many times as you pass it.
Because in Array(noOfBrains + 1).join(" " + this.mastermind) this.mastermind contains the string "Brain". and noOfBrains is '4'. so it becomes Array(4+1).join(" " +"Brain") into Array(5).join(" Brain") will show the output as Brain Brain Brain Brain
This creates an array of a given length with undefined elements. In this example length of 5. When 5 elements are joined together there are 4 delimiters and each is delimiter is " Brain"
var dummyArray = Array(5);
console.log("Our Dummy Array");
console.log(dummyArray);
console.log();
console.log("Our Dummy Array Joined More Conventially");
console.log(dummyArray.join(","));
console.log();
console.log("Our Dummy Array Joined More Brainly");
console.log(dummyArray.join(" Brain"));
console.log();
Array join joins all elements of array to string using some string glue.
var a = ['one', 'two', 'three'];
console.log(a.join(', '));
You will see "one, two, three" in the console.
In your case glue is " Brain". Array is [5] - i mean array with one element which is 5 (4 + 1 = 5). So, [5].join(' Brain') = "5"
If you need repeat some string 2 or more times, you can use String.repeat(times).
In your case:
var bcObject = {
mastermind : "Brain",
henchman: "Pinky",
battleCry: function (noOfBrains) {
return "They are " + this.henchman + " and the" +
(' ' + this.mastermind).repeat(noOfBrains);
}
};
var battleCry = bcObject.battleCry(4);

How to add spaces in the first and the end of a string variable

I'm trying to add spaces in the first and the end of this string variable, I tried to convert the string to an array, then add space with push() and unshift() ... but it returns "x.push is not a function"
function space_fb(x){
x.split(" ");Array.prototype.slice.call
x.push (" ") ;
x.unShift (" ") ;
return x.join(" ");;
}
var xxx = "Medardo";
space_fb(xxx);
alert(xxx);
There is many ways this can be done you could simply add the spaces in your string value for example like " Medardo " and it will work, But My example would handle dynamic string data.
You dont need that space_fb function at all its dead simple:
var xxx = " " + "Medardo" + " ";
alert(xxx);
Edited as OP wanted it in a function as his "teacher wants him to"
function AddSpaces(x){
return " " + x + " ";
}
var xxx = AddSpaces("Medardo")
alert(xxx);
How about this? JSON.stringify ist just to show the output in this way.
var x = "foo";
function addSpaces(string){
var a = string.split("");
a.push(" ");
a.unshift(" ");
return a.join("");
}
document.write(JSON.stringify(addSpaces(x)));
This is because you are using method split but the variable is not being assign
you have two options
1.- x = x.split();
or
2.- var myArray = x.split(" ");
This is all you will need do not use the + + operators. A . is a concatenation operator.
var xxx = ' '.xxx.' ';
As mentioned by #itsgoingdown, in JavaScript you can append strings using the + operator. There is really no need to split the string into a character array and push/unshift to add spacing.
function space_fb(x){
x.split("");Array.prototype.slice.call
x.push (" ") ;
x.unShift(" ") ;
return x.join("");;
}
var xxx = "Medardo";
space_fb(xxx);
alert(xxx);

Modifying an existing RegEx to accommodate also replacing <nbsp;>'s with a blank space

I need your help,
How can the existing code below be modified such that it not only takes into account replacing all the <br>'s with \n's but also all the <nbsp;>'s anywhere in a string with the space separator in javascript?
Here is the existing code that needs to be modified:
var txt = str.replace(/<br\s*\/?>/mg,"\n")
If you want to do it with one regexp, replace accepts a function as the replacer so you could leverage that with a group match:
var str = 'some string <br/> and something else';
var txt = str.replace(/(<br\s*\/?>| )/mg, function (match) {
return match === ' ' ? ' ' : '\n';
});
document.write('<pre>' + txt + '</pre>');
If not, you can also chain together as many replace calls as you want:
var str = 'some string <br/> and something else';
var txt = str.replace(/<br\s*\/?>/gm, '\n').replace(/ /gm, ' ');
document.write('<pre>' + txt + '</pre>');
The main benefit of using one replace is that it won't need to check the entire string twice. However this does make the code a bit harder to read and possibly to maintain if you need to add/edit which entities you want to replace. So depending on the length of the string to be checked you would need to strike a balance between performance and readability/maintainability.
You may use something like this
var txt = str.replace(/<br ?/?>/g, '\n').replace(/ /g, ' ');
but you can't do 2 replacements using 1 regex

javascript to reverse order of values

How can I reverse the order of Duck, Donald with Javascript?
I am currently retrieving Duck, Donald from a query string and I would like to be able to display it on the page, receiving it as Dondald Duck.
I am using document.write("Name: " + Request.QueryString("name")); to write Duck, Donald to the page and I would also like to be able to change 'Mouse', 'Mickey G' to just 'Mickey Mouse'.
var name = Request.QueryString("name").Item(1).split(",").reverse().join(" ").trim();
if(name.split(" ").length > 2) {
name = name.split(" ");
name.splice(1, 1);
name = name.join(" ");
}
document.write(name);
Example at http://jsfiddle.net/6AdGs/
You can split the string using split method, and then past them in correct order:
var str = 'Duck, Donald';
var parts = str.split(',');
document.write(parts[1] + ' ' + parts[0]);
Basically thats what you need to do. Hope it helps!
This function may help you.
<script>
function reverseName(str) {
var tail = str.substr(0, str.indexOf(","));
var head = str.substr(str.indexOf(",") + 1);
return head + ' ' + tail;
}
document.write("Name: " + reverseName(Request.QueryString("name")));
</script>
As above, but consider: Are first names and surnames always separated by commas? It becomes relevant with some non-English names you may find like 'Silva dos Santos, Miguel Jesus', where Silva dos Santos are the family names and Miguel Jesus are given names.

Categories