Javascript - split string and output results on separate lines - javascript

What I'm trying to do is take a comma separated string like "HTML5,CSS3,Compass,JavaScript,jQuery,PHP,Foundation,Drupal,WordPress" - split that string into and array and write a loop that outputs each array item on a separate line.
This works:
function splitstr() {
var splitStr = "HTML5,CSS3,Compass,JavaScript,jQuery,PHP,Foundation,Drupal,WordPress";
var output = splitStr.split(',');
for (var i = 0; i < output.length; i++) {
document.write(output[i] + "<br />");
}
}
but obviously it outputs to a blank page. I need it to output the results into a div.
So I try the following code but it doesn't work. It only prints out the last one "Wordpress".
function splitstr() {
var splitStr = "HTML5,CSS3,Compass,JavaScript,jQuery,PHP,Foundation,Drupal,WordPress";
var output = splitStr.split(",");
for (var i = 0; i < output.length; i++) {
document.getElementById("splitres").innerHTML = output[i] + "<br />";
}
}
what am i doing wrong?
agon

document.getElementById("splitres").innerHTML += output[i] + "<br />";
Note +. With that, you are appending HTML; without it, you are overwriting it.

Related

Why is not working when i try to add a to a string to my array location

I'm still learning JavaScript, and now I'm in the array chapter and I'm doing this project I have to ask the user for 5 names and stored and my array, then have to sort the names by the location in the array, so i could separed in odd and in even, then i have to add a lastname to the odds, and different last name to the even, but is that part that is not working any help ... THANKS
var numberfirstNames = 5;
var userMessage = " Please enter a first Name" ;
var secondArray = [];
var odd2 = [];
var even2 = [];
for (var i = 0; i < numberfirstNames; i++) // loop 5 times LOOL ASKING FOR "5" FIRST NAMES>> STORING IN NAMES
{
secondArray[i] = getFirstname();
window.alert("second " + secondArray[i] );
}
for (var i = 0; i < secondArray.length; i++) {
if(i % 2 === 0) // index is even
{
even2.push(secondArray[i]);
for ( var i=0 ; i<even2.length; i++)
even2[i]+=" Chavez"
}
else
{
odd2.push(secondArray[i]);
for ( var i=0 ; i<odd2.length; i++)
odd2[i]+=" McCain"
}
}
document.write(" \n all the names: "+ secondArray+'<br>');
document.write(" \n even names: "+ even2+'<br>');
document.write(" \n odd names: "+ odd2+'<br>');
The problem is that you are making a second loop that is unnecessary... the code
for ( var i=0 ; i<even2.length; i++)
and
for ( var i=0 ; i<odd2.length; i++)
should be simply removed.
You need to add first or last name only to last element added to odd2 or even2 and this can be done with:
even2[even2.length-1]+=" Chavez"
and
odd2[odd2.length-1]+=" McCain"
It is important to get used adding correct indentation because this kind of error is much easier to spot in the code when it is properly indented.
You don't need to loop again to add the specific last name. You can just prepend it while you are inserting it into the array like below.
var numberfirstNames = 5;
var userMessage = " Please enter a first Name";
var secondArray = [];
var odd2 = [];
var even2 = [];
// loop 5 times LOOP ASKING FOR "5" FIRST NAMES >> STORING IN NAMES
for (var i = 0; i < numberfirstNames; i++) {
secondArray[i] = getFirstname();
window.alert("second " + secondArray[i]);
if (i % 2 === 0) {
even2.push(secondArray[i] + " Chavez");
} else {
odd2.push(secondArray[i] + " McCain");
}
}
document.write(" \n all the names: " + secondArray.join(",") + '<br>');
document.write(" \n even names: " + even2.join(",") + '<br>');
document.write(" \n odd names: " + odd2.join(",") + '<br>');

Parsing some JSON

I have a complex JSON file that needs parsing and my loop skills (or more precisely, the lackthereof), are really failing me.
I have the following xml file, and I am trying to get all elements on one row. In my perfect world (in no particular order)...
sku #, length, width, image, description, attribute value 1, attribute value 2, attribute value 3, etc.
The JSON file is as follows:
var json = {
"product":[
{
"shipdata":{
"_length":"2in",
"_width":"2in",
},
"sku":"90245",
"brand":"Brandy",
"image":"shirt.jpg",
"description":"description",
"attributes":{
"attribute":[
{
"_name":"Color",
"_value":"Black",
},
{
"_name":"Gender",
"_value":"Mens",
},
{
"_name":"Size",
"_value":"L",
},...
So, my intended result is:
90245, Brandy, Black, Men's, L, shirt.jpg, 2in, 2in
But when I loop like the following, I only get the first result for "name". Admittedly, I'm a newb, but if anyone can push me in the right direction or show a proof of concept, it would be so so appreciated. Thanks in advance / feel horrible to even ask such a low level question.
for(var l = 0; l < json.product[i].attributes.attribute.length; l++) {
var xxx = (json.product[i].attributes.attribute[l]['_name']);
}
$('body').append(xxx);
if you don't mind using lodash, this should help you:
var res=[];
_.each(json.product, function(p) {
res.push(p.brand);
res.push(p.sku);
_.each(p.attributes.attribute, function(at) {
res.push(at._value);
});
});
console.log(res.join(','));
//Brandy,90245,Black,Mens,L
working fiddle
EDIT: My solution is obviously not as good as scottjustin5000 's. I'm trying to explain the detailed steps on analyzing this problem.
You want to output a string from the JSON data. So we should break the parts of the string and process one by one.
90245, Brandy, Black, Men's, L, shirt.jpg, 2in, 2in
"sku", "brand", attribute, attribute, attribute, "image", "_length", "_width"
Let's start.
function parseJSONToLine(product) {
var line = "";
line = line + product["sku"] + ", ";
line = line + product["brand"] + ", ";
line += getAllAttributes(product);
line = line + product["image"] + ", ";
line = line + product["shipdata"]["_length"] + ", ";
line = line + product["shipdata"]["_width"];
return line;
}
products = json["product"];
for (var i = 0; i < products.length; i++) {
console.log(parseJSONToLine(products[i]));
}
This part is just assembling the line your want part by part. For the attributes, we need another loop:
function getAllAttributes(product) {
var attrStr = "";
var attrsDict = {};
var attrsOrder = ["Color", "Gender", "Size"];
var attrList = product["attributes"]["attribute"];
// loop through every attribute and put it in dictionary
for (var i = 0; i < attrList.length; i++) {
attrsDict[attrList[i]["_name"]] = attrList[i]["_value"];
}
for (var i = 0; i < attrsOrder.length; i++) {
attrStr = attrStr + attrsDict[attrsOrder[i]] + ", ";
}
return attrStr;
}
The last part is to put the line produced into your HTML. Just the $(body') line with:
$('body').append('<p>' + line + '</p>');
That's it. The point to solve this problem is to know what the line is consisted of. Then try to get the values in the JSON object one by one. When meeting something seems to be complicated, just try to write out the code and modify according to the output. console.log() is very helpful on this.
The reason of why your code doesn't work is, your JSON data contains not only arrays but also objects. You have to take them apart.
If you need further explanation on the snippet, comment me.
JSFiddle: https://jsfiddle.net/aresowj/g9wuLg28/
According to your JSON structure and the output you want, I'll suggest to do the following:
var output = Array(json.product.length); // will be an array of string
for(var i = 0; i < json.product.length; i++) {// loop on each product
output[i] = json.product[i].sku +', '+json.product[i].brand; // according to your question, seems that you want these 2 things first
for(var j = 0; j < json.product[i].attributes. attribute.length; j++){ // then we loops on the attributes
output[i] += ', ' +json.product[i].attributes. attribute[j]._name;
}
output[i] += ', ' +json.product[i].shipdata._length + ', ' + json.product[i].shipdata._width; // last we append to the string the with and height data
}
$('body').append(output)
var json = {
"product":[
{
"shipdata":{
"_length":"2in",
"_width":"2in",
},
"sku":"90245",
"brand":"Brandy",
"image":"shirt.jpg",
"description":"description",
"attributes":{
"attribute":[
{
"_name":"Color",
"_value":"Black",
},
{
"_name":"Gender",
"_value":"Mens",
},
{
"_name":"Size",
"_value":"L",
}
]
}
}
]
};
var output = Array(json.product.length); // will be an array of string
for(var i = 0; i < json.product.length; i++) {// loop on each product
output[i] = json.product[i].sku +', '+json.product[i].brand; // according to your question, seems that you want these 2 things first
for(var j = 0; j < json.product[i].attributes. attribute.length; j++){ // then we loops on the attributes
output[i] += ', ' +json.product[i].attributes. attribute[j]._name;
}
output[i] += ', ' +json.product[i].shipdata._length + ', ' + json.product[i].shipdata._width; // last we append to the string the with and height data
}
$('body').append(output)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
A solution using Array.map:
var res = json.product.map(function (p) {
return [p.sku, p.brand].concat(p.attributes.attribute.map(function (at) {
return at._value;
}))
});
res.forEach(function (r) { console.log(r.join(', ')) });
https://jsfiddle.net/xve4agp6/1/

Need for/while/do while loops to repeat asterisks

I have this problem, to repeat 30 asterisks for 3 lines. I made this example code but it repeats 30 numbers (1..30) from 1 number for first line, up to 30 numbers for the last line. So, I'd need the code to repeat 30 asterisks, for 3 lines each but not quite like within this code.
Sorry for bad elaboration.
var text = "";
var max = 30;
for(i = 0; i < max; i++)
{
for(j = 0; j <= i; j++)
{
text += (j+1)+" ";
}
text += "<br />";
}
A more re-usable solution will be to make a generic repeatString function that simply makes multiple copies of any string.
function repeatString(s, times) {
for (var i = 0, r = ''; i < times; i++) {
r += s;
}
return r;
}
var line = repeatString('*', 30) + '<br />',
content = repeatString(line, 3);
http://jsfiddle.net/611y2vmz/1/
Repeat the loop three times, like this:
for ( var i = 0; i < 3; i++ ) { // this is the line loop
for ( var j = 0; j < 30; j++ ) { //this is the asterix loop
document.write('*');
}
document.write('<br>');
}
Here's a simple demo
If you are using ES2015 (ES6) syntax you can leverage repeat function and string templating. Using those features your code will look like this
let text = (`${'*'.repeat(30)}<br/>`).repeat(3);
Here is an example of ES2015 (ES6) code
if you are using ES5 then you can do this way:
String.prototype.repeat = function(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
};
var text = ('*'.repeat(30) + '<br/>').repeat(3);
Here is an example of ES5 code
You need your outer loop to iterate 3 times, and your inner loop to iterate 30 times. Each iteration of your inner loop should add an asterisk (instead of adding j+1 like you are doing now). This will produce 3 rows of 30 asterisks.
var TEXT = "*";
var LINE_SEPARATOR = "<br/>";
var TEXT_COUNT = 30;
var LINE_COUNT = 3;
var output = "";
for (line = 1; line <= LINE_COUNT; ++line) {
for (text = 1; text <= TEXT_COUNT; ++text) {
output += TEXT;
}
output += LINE_SEPARATOR;
}
document.write(output);
An alternative would be to use recursion:
function stars(num) {
return num > 0 ? stars(num - 1) + '*' : '';
}
var content = stars(30) + '<br/>' + stars(30) + '<br/>' + stars(30);
DEMO

Javascript: using a for statement as a variable

I'm fairly new to javascript and something I've been playing with lately is the 'for' statement. I'm questioning one thing, though. I've learned how to make a 'for' statement do things as if it was an output, like this:
for (i = 0; i < 3; i++) {
console.log(i);
}
But what if you want to set a variable for the whole output of the 'for' statement?
var destinationArray = ["town", "areas", "bosses"];
var destinationArraySet = 1;
var i;
for ( i = 0; i < destinationArraySet; i++) {
console.log(destinationArray[i]);
} /*the whole thing should be equal to var destination */
var userDestinationPrompt = ("Where would you like to go? Available places: " +
/* var destination */
+
".").toUpperCase();
To give some more context: I'm making a game that allows further destinations when the destination before is cleared. Once that's achieved, I set destinationArraySet to a higher value, which means that more places would be logged and put after 'Available places'.
Help would be very appreciated! If there's something not clear enough let me know.
The for statement is not an expression, so it doesn't have a return value. Use a variable to collect values in the loop:
var destination = '';
for (var i = 0; i < destinationArraySet; i++) {
destination += destinationArray[i] + ' ';
}
Of course, if you only want to concatenate the values in part of an array, you can use the slice method to get part of it, then the join method:
var destination = destinationArray.slice(0, destinationArraySet).join(' ');
var destination = '';
var destinationArray = ["town", "areas", "bosses"];
var destinationArraySet = 1;
for (var i = 0; i < destinationArraySet; i++) {
destination += destinationArray[i] + '\n';
}
console.log(destination);
Try this -
var destinationArray = ["town", "areas", "bosses"];
var destinationArraySet = 1;
var i;
var availablePlaces = '';
var separator = '';
for ( i = 0; i < destinationArraySet; i++) {
availablePlaces += separator + destinationArray[i];
separator = ', ';
}
var userDestinationPrompt = ("Where would you like to go? Available places: " +
availablePlaces + ".").toUpperCase();
The for statement doesn't have an "output", it's not a function. Thinking for as a function will give you troubles later on. for is simply a statement that continuously execute the block of code inside. It does not "output", or in other words, return any value.
Do this instead:
var destinationArray = ["town", "areas", "bosses"], destinationArraySet = 1;
var userDestinationPrompt = ("Where would you like to go? Available places: " +
destinationArray.slice(0, destinationArraySet).join("\n")
+ ".").toUpperCase();
prompt(userDestinationPrompt);
Demo: http://jsfiddle.net/7c2b9q7m/1/
destinationArray.slice(0, destinationArraySet): Cuts the array to the specified length.
.join("\n"): Join the newly created array by \ns (newline) to micic the default console.log behavior.

textarea duplicate string check ignoring leading and trailing whitespace

Users will enter various serials in a textarea. Each newline will indicate a new serial. Some requirements/restrictions:
Leading and trailing white spaces are not allowed.
White space within a serial is okay.
Blank serials are not allowed
I'd prefer to not use JQuery.
Store duplicates so they can be shown to the user.
Based on my tests I have a working solution. I want to make sure I'm not missing or overlooking anything. My questions are:
Is there a more efficient ways to check for duplicates?
Are there any glaring test cases that my solution won't catch?
Working Example: http://jsbin.com/ivusuj/1/
function duplicateCheck() {
var output = document.getElementById('Output');
output.innerHTML = '';
var duplicateSerials = [];
var count = 0;
var textArea = document.getElementById('Serials');
var serials = textArea.value.trim().split(/ *\n */);
for(var i = 0;i < serials.length;i++){
var serial = serials[i];
if(serials.indexOf(serial) != serials.lastIndexOf(serial) &&
duplicateSerials.indexOf(serial) == -1 && serial !== '') {
duplicateSerials.push(serial);
}
}
// For testing
output.innerHTML = '<pre>Serials:\t' + serials.toString() + "<br />" +
'Duplicates:\t' + duplicateSerials.toString() + "<br>" +
'</pre>';
}
Note: the above is for a client side check. The same check will be performed server side as well to ensure the data is valid.
Update
Solution comparison: http://jsbin.com/ivusuj/4/edit
I put together a jsfiddle her: http://jsfiddle.net/wrexroad/yFJjR/3/
Actually checking for duplicates that way is pretty inefficient.
Instead of checking for duplicates, this just adds a property to an object where the property's name is is the serial. Then it prints out all of the property names.
This way if you have duplicates, it will just create the property, then overwrite it.
Here is the function:
function duplicateCheck() {
var output = document.getElementById('Output');
output.innerHTML = '';
var textArea = document.getElementById('Serials');
var inputSerials =
textArea.value.trim().split(/ *\n */);
var outputSerials = new Object();
for(var i = 0;i < inputSerials.length;i++){
var serial = inputSerials[i];
//build an object whose properties are serials
//if the serial exists, incremint a counter
if(outputSerials[serial]){
outputSerials[serial]++;
}else{
outputSerials[serial] = 1;
}
}
output.innerHTML =
'Serials: <br />';
for(var i in outputSerials){
output.innerHTML += i + " ";
}
output.innerHTML +=
'<br /><br />Duplicate Serials: <br />';
for(var i in outputSerials){
//check to see if we have any duplicates
if(outputSerials[i] > 1){
output.innerHTML += i + " ";
}
}
}
I think you'd get significantly better performance if you used an object to determine which serials you'd seen before. Something closer to this:
var seen = {};
for (var i = 0, j = serials.length; i < j; ++i) {
var serial = serials[i];
if (seen.hasOwnProperty(serial)) {
// Dupe code goes here.
continue;
}
// Can't be a duplicate if we get to this point.
}
Though that won't work with serials that use periods.
Here's a solution to filter out duplicates.
function formatInput() {
var arrUnique = [], dups = [],
str = document.getElementById('Serials').value
.replace(/\r\n?/g,'\n')
// normalize newlines - not sure what PC's
// return. Mac's are using \n's
.replace(/(^((?!\n)\s)+|((?!\n)\s)+$)/gm,'')
// trim each line
.replace(/^\n+|\n+$|\n+(?=\n(?!\n))/g,''),
// delete empty lines and trim the whole string
arr = str.length ? str.split(/\n/) : [];
// split each line, if any
for (var i = 0; i < arr.length; i++) {
if (arrUnique.indexOf(arr[i]) == -1)
arrUnique.push(arr[i]);
else dups.push(arr[i]);
}
//document.getElementById('Serials').value = arrUnique.join('\n');
console.log('serials:', arr);
console.log('unique:', arrUnique);
console.log('duplicates:', dups);
}

Categories

Resources