Function to number array elements outputs "undefined" - javascript

I want to number each item in an Array, like this:
["hello", "hi", "hey"].number()
> ["1. hello", "2. hi", "3. hey"]
Here's my code:
Array.prototype.number = function () {
var tempNum = this;
for (i in this) {
tempNum[i] = tempNum[(i + 1)] + ". " + tempNum[i]
}
return tempNum;
}
But this is the output:
["hello", "hi", "hey"].number()
> ["undefined. hello", "undefined. hi", "undefined. hey"]
Why? How should I implement this and why is my code not working?

I think you want something like this:
for(var i=0, len = this.length; i<len; i++){
tempNum[i] = (i + 1) + ". " + tempNum[i];
}
you're using tempNum when you shouldn't be in the right side of your equation. The reason you're getting "undefined" is because at some point in your current equation you're getting an index outside of the length of your array.

The ES5 way:
Array.prototype.number = function () {
return this.map( function ( value, i ) {
return ( i + 1 ) + '. ' + value;
});
};
Live demo: http://jsfiddle.net/XSYTK/1/
You'll need to shim .map() for IE8.

Inside your for loop, you're doing:
tempNum[i] = tempNum[(i + 1)] + ". " + tempNum[i]
If you just want to add numbers before each value, why are you getting tempNum[(i + 1)]?
It should look like:
Array.prototype.number = function () {
var tempNum = this;
for (var i in this) {
tempNum[i] = (parseInt(i,10) + 1) + ". " + tempNum[i];
}
return tempNum;
}
Note the parseInt(i,10)+1. This adds one to the index (after converting it to an int), and then prepends that to the string.

tempNum[(i + 1)] is not what you want to do, you want something like (i + 1). This also don't work, because keys are always strings. To type cast them to a float you can use (parseFloat(i) + 1) or, what is nicer, (~~(i) + 1). The total code become:
Array.prototype.number = function () {
var tempNum = this;
for (i in this) {
tempNum[i] = (~~(i) + 1) + ". " + tempNum[i]
}
return tempNum;
};
console.log(["hello", "hi", "hey"].number());
// > ["1. hello", "2. hi", "3. hey"]

I would not try to modify the array values itself when invoking the number() function, because if you invoke the function again on the same array the numbering gets doubled. Instead better make a new array and return it like this:
Array.prototype.number = function () {
var ret=[];
var len=this.length;
for(var i=0;i<len;i++){
ret.push((i+1)+'. '+this[i]);
}
return ret;
}
console.log(["hello", "hi", "hey"].number());
Demo: http://jsfiddle.net/LcHsY/

The problem with your current solution is that in each iteration, i holds the value of the element, instead of the index.
So, when you do things like
tempNum[(i + 1)]
you are trying to add "hello" and 1, and this gives an undefined result.
So, in order to get your code working you could change your code as follows:
Array.prototype.number = function () {
var tempNum = this;
for (var i = 0; i < tempNum.length; ++i) {
tempNum[i] = (i + 1) + ". " + tempNum[i]
}
return tempNum;
}

Related

Missing element in the function

This function should create and display an array with numbers. There is some element missing which prevents this array from displaying and so fulfilling the "console.log" assumptions:
function createArray(number) {
var newArray = [/*10*/];
for(var counter = 1; counter <= number; counter++) {
newArray.push(counter);
}
}
console.log("table with numbers up to 6 = " + createArray(6));
console.log("table with numbers up to 1 = " + createArray(1));
console.log("Testing negatives (should display an empty array) " + createArray(-6));
console.log("Testing 0 (should display an empty array) " + createArray(0));
Could you analyze this and provide some feedback, please?
You're missing return newArray; at the end of the function. If there's no return statement, the function returns undefined by default.
function createArray(number) {
var newArray = [/*10*/];
for(var counter = 1; counter <= number; counter++) {
newArray.push(counter);
}
return newArray;
}
console.log("table with numbers up to 6 = " + createArray(6));
console.log("table with numbers up to 1 = " + createArray(1));
console.log("Testing negatives (should display an empty array) " + createArray(-6));
console.log("Testing 0 (should display an empty array) " + createArray(0));
Well, there is nothing wrong with your function, just you are not returning the array created, just add:
return newArray at the end of the function, linke this:
function createArray(number) {
var newArray = [/*10*/];
for(var counter = 1; counter <= number; counter++) {
newArray.push(counter);
}
return newArray;
}

Returning a String instead of looping print statement

I'm new to Javascript and I'm curious as to how to store values in a string and then return it. In the example below 2 numbers are picked, for example 2 and 8, and the program should return 2x1 =2, 2x2=4,..... all the way up to 2x8 =16. This can obviously be done by constantly looping a print statement as I have done, but how would I be able to store all the values in a String and then return the string.
function showMultiples (num, numMultiples)
{
for (i = 1; i < numMultiples; i++)
{
var result = num*i;
console.log(num + " x " + i + " = " + result+ "\n");
}
}
console.log('showMultiples(2,8) returns: ' + showMultiples(2,8));
console.log('showMultiples(3,2) returns: ' + showMultiples(3,2));
console.log('showMultiples(5,4) returns: ' + showMultiples(5,4));
function showMultiples(num, numMultiples) {
// the accumulator (should be initialized to empty string)
var str = "";
for (i = 1; i < numMultiples; i++) {
var result = num * i;
// use += to append to str instead of overriding it
str += num + " x " + i + " = " + result + "\n";
}
// return the result str
return str;
}
var mulOf5 = showMultiples(5, 10);
console.log("multiples of 5 are:\n" + mulOf5);
The operator += add the a value (right operand) to the previous value of the left operand and stores the result in the later. So these two lines are the same:
str = str + someValue;
str += someValue;
You could just use string concatenation:
var finalResult = ""
...in your loop...
finalResult += num + " x " + i + " = " + result+ "\n"
Often you can also just collect the results in an array and use join to append them.
var lines = [];
... in your loop:
lines.push(num + " x " + i + " = " + result);
... afterwards
console.log(lines.join("\n"));
In case you wanted to use ES6 syntax using backticks for a template string, you can use the below. This is a little more readable and is exactly where it is useful (so long as you can use ES6 wherever you're using JavaScript).
function showMultiples(num, numMultiples){
let result = '';
for(let i = 1; i < numMultiples; i++){
result += `${num} x ${i} = ${i * num}\n`;
};
return result;
}
console.log(showMultiples(2,8));

How to call a javascript function with string arrays

Can anyone please tell me how to call javascript function with string arrays as argument and how to use this arrays in the called function.
Here is my code:
C# Code
for (int i = 0; i < count; i++)
{
array1[i] = dt.Rows[i]["FieldName"].ToString();
array2[i] = dt.Rows[i]["FieldValue"].ToString();
}
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"Javascript", "<script type='text/javascript'>myFunction('" + count + "','" + array1 + "','" + array2 + "');</script>");
JavaScript
function myFunction(cnt, arr1, arr2)
{
for (i = 0; i < cnt; i++)
{
alert("fname" + arr1[i] + " :fvalue " + arr2[i] + " :count:" + cnt);
}
}
any syntax error in passing array variables.
You could leverage javascript's apply method here and use arguments variable and treat it as the source of your array thereby avoiding messy 'args' on your method. You can then pass a string like:
//After ensuring all elements in array1 are wrapped in ' characters or are appropriate as arguments as-is
"myFunction.apply(this, [" + array1.join(",") + "])".
This way "myFunction" will handle ANY number of arguments or (using the javascript arguments object) array of any size. No need to pass 'count' variable. myFunction will could then be written as:
function myFunction() {
for (var j = 0, len = arguments.length; j < len; j++) {
var a = arguments[j];
//do something with a
}
}
How to call a javascript function with string arrays
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"Javascript", "<script type='text/javascript'>myFunction('" + count + "','[" +string.Join(",", array1) + "]','[" + string.Join(",", array2)+ "]');</script>");
nb : you can save the scripts tag via :
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(),"Javascript", "myFunction('" + count + "','[" +string.Join(",", array1) + "]','[" + string.Join(",", array2)+ "]');",true);
Also , you're adding the same key again and again ( "Javascript") :
try adding guid :
"Javascript"+Guid.NewGuid().ToString("n")

Replace everything between two strings with numbers i++ {0},{1}

Have mechanism that replaces strings like .NET string.Format in javascript ("{0} - {1}",'a','b') would result "a - b".
I am looking for mechanism that would Replace everything between two strings with {0}{1}...
Example :
var str = "([OrderDate] >= Func:{TheApplication().GetProfileAttr('TestDate')} ) and [OrderDate] < 1/1/2013 AND [Name] = Func:{TheApplication().GetProfileAttr('Name')}"
stringFormatProducer(str,"Func:{","}");
would give result
"([OrderDate] >= {0} ) and [OrderDate] < 1/1/2013 AND [Name] = {1}"
I have this mechanism done in horrid way where I am splitting it on Func:{ then } then iterating over it, I am sure someone already has a better solution.
var i = 0;
str.replace(/Func:{[^}]+}/g, function(c) {
return '{' + i++ + '}';
});
Or more flexible way:
var i = 0,
func = 'Func:';
str.replace(new RegExp(func + '{[^}]+}', 'g'), function(c) {
return '{' + i++ + '}';
});
A complete method for you:
String.prototype.createFormattingString = function(prefix, open, close) {
var re = new RegExp(prefix + open + '[^' + close + ']+' + close, 'g'),
i = 0;
return this.replace(re, function(c) {
return '{' + i++ + '}';
});
};
'(VAR > Func:{ some text })'.createFormattingString('Func:', '{', '}');
'(VAR > Func:[ some text ])'.createFormattingString('Func:', '\\[', '\\]');

Get textual (string) version of an object - displaying in the browser for debugging purposes [duplicate]

I'm trying to find a way to "pretty print" a JavaScript data structure in a human-readable form for debugging.
I have a rather big and complicated data structure being stored in JS and I need to write some code to manipulate it. In order to work out what I'm doing and where I'm going wrong, what I really need is to be able to see the data structure in its entirety, and update it whenever I make changes through the UI.
All of this stuff I can handle myself, apart from finding a nice way to dump a JavaScript data structure to a human-readable string. JSON would do, but it really needs to be nicely formatted and indented. I'd usually use Firebug's excellent DOM dumping stuff for this, but I really need to be able to see the entire structure at once, which doesn't seem to be possible in Firebug.
Use Crockford's JSON.stringify like this:
var myArray = ['e', {pluribus: 'unum'}];
var text = JSON.stringify(myArray, null, '\t'); //you can specify a number instead of '\t' and that many spaces will be used for indentation...
Variable text would look like this:
[
"e",
{
"pluribus": "unum"
}
]
By the way, this requires nothing more than that JS file - it will work with any library, etc.
I wrote a function to dump a JS object in a readable form, although the output isn't indented, but it shouldn't be too hard to add that: I made this function from one I made for Lua (which is much more complex) which handled this indentation issue.
Here is the "simple" version:
function DumpObject(obj)
{
var od = new Object;
var result = "";
var len = 0;
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
value = "'" + value + "'";
else if (typeof value == 'object')
{
if (value instanceof Array)
{
value = "[ " + value + " ]";
}
else
{
var ood = DumpObject(value);
value = "{ " + ood.dump + " }";
}
}
result += "'" + property + "' : " + value + ", ";
len++;
}
od.dump = result.replace(/, $/, "");
od.len = len;
return od;
}
I will look at improving it a bit.
Note 1: To use it, do od = DumpObject(something) and use od.dump. Convoluted because I wanted the len value too (number of items) for another purpose. It is trivial to make the function return only the string.
Note 2: it doesn't handle loops in references.
EDIT
I made the indented version.
function DumpObjectIndented(obj, indent)
{
var result = "";
if (indent == null) indent = "";
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
value = "'" + value + "'";
else if (typeof value == 'object')
{
if (value instanceof Array)
{
// Just let JS convert the Array to a string!
value = "[ " + value + " ]";
}
else
{
// Recursive dump
// (replace " " by "\t" or something else if you prefer)
var od = DumpObjectIndented(value, indent + " ");
// If you like { on the same line as the key
//value = "{\n" + od + "\n" + indent + "}";
// If you prefer { and } to be aligned
value = "\n" + indent + "{\n" + od + "\n" + indent + "}";
}
}
result += indent + "'" + property + "' : " + value + ",\n";
}
return result.replace(/,\n$/, "");
}
Choose your indentation on the line with the recursive call, and you brace style by switching the commented line after this one.
... I see you whipped up your own version, which is good. Visitors will have a choice.
You can use the following
<pre id="dump"></pre>
<script>
var dump = JSON.stringify(sampleJsonObject, null, 4);
$('#dump').html(dump)
</script>
In Firebug, if you just console.debug ("%o", my_object) you can click on it in the console and enter an interactive object explorer. It shows the entire object, and lets you expand nested objects.
For Node.js, use:
util.inspect(object, [options]);
API Documentation
For those looking for an awesome way to see your object, check prettyPrint.js
Creates a table with configurable view options to be printed somewhere on your doc. Better to look than in the console.
var tbl = prettyPrint( myObject, { /* options such as maxDepth, etc. */ });
document.body.appendChild(tbl);
I'm programming in Rhino and I wasn't satisfied with any of the answers that were posted here. So I've written my own pretty printer:
function pp(object, depth, embedded) {
typeof(depth) == "number" || (depth = 0)
typeof(embedded) == "boolean" || (embedded = false)
var newline = false
var spacer = function(depth) { var spaces = ""; for (var i=0;i<depth;i++) { spaces += " "}; return spaces }
var pretty = ""
if ( typeof(object) == "undefined" ) { pretty += "undefined" }
else if ( typeof(object) == "boolean" ||
typeof(object) == "number" ) { pretty += object.toString() }
else if ( typeof(object) == "string" ) { pretty += "\"" + object + "\"" }
else if ( object == null) { pretty += "null" }
else if ( object instanceof(Array) ) {
if ( object.length > 0 ) {
if (embedded) { newline = true }
var content = ""
for each (var item in object) { content += pp(item, depth+1) + ",\n" + spacer(depth+1) }
content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
pretty += "[ " + content + "\n" + spacer(depth) + "]"
} else { pretty += "[]" }
}
else if (typeof(object) == "object") {
if ( Object.keys(object).length > 0 ){
if (embedded) { newline = true }
var content = ""
for (var key in object) {
content += spacer(depth + 1) + key.toString() + ": " + pp(object[key], depth+2, true) + ",\n"
}
content = content.replace(/,\n\s*$/, "").replace(/^\s*/,"")
pretty += "{ " + content + "\n" + spacer(depth) + "}"
} else { pretty += "{}"}
}
else { pretty += object.toString() }
return ((newline ? "\n" + spacer(depth) : "") + pretty)
}
The output looks like this:
js> pp({foo:"bar", baz: 1})
{ foo: "bar",
baz: 1
}
js> var taco
js> pp({foo:"bar", baz: [1,"taco",{"blarg": "moo", "mine": "craft"}, null, taco, {}], bleep: {a:null, b:taco, c: []}})
{ foo: "bar",
baz:
[ 1,
"taco",
{ blarg: "moo",
mine: "craft"
},
null,
undefined,
{}
],
bleep:
{ a: null,
b: undefined,
c: []
}
}
I've also posted it as a Gist here for whatever future changes may be required.
jsDump
jsDump.parse([
window,
document,
{ a : 5, '1' : 'foo' },
/^[ab]+$/g,
new RegExp('x(.*?)z','ig'),
alert,
function fn( x, y, z ){
return x + y;
},
true,
undefined,
null,
new Date(),
document.body,
document.getElementById('links')
])
becomes
[
[Window],
[Document],
{
"1": "foo",
"a": 5
},
/^[ab]+$/g,
/x(.*?)z/gi,
function alert( a ){
[code]
},
function fn( a, b, c ){
[code]
},
true,
undefined,
null,
"Fri Feb 19 2010 00:49:45 GMT+0300 (MSK)",
<body id="body" class="node"></body>,
<div id="links">
]
QUnit (Unit-testing framework used by jQuery) using slightly patched version of jsDump.
JSON.stringify() is not best choice on some cases.
JSON.stringify({f:function(){}}) // "{}"
JSON.stringify(document.body) // TypeError: Converting circular structure to JSON
Taking PhiLho's lead (thanks very much :)), I ended up writing my own as I couldn't quite get his to do what I wanted. It's pretty rough and ready, but it does the job I need. Thank you all for the excellent suggestions.
It's not brilliant code, I know, but for what it's worth, here it is. Someone might find it useful:
// Usage: dump(object)
function dump(object, pad){
var indent = '\t'
if (!pad) pad = ''
var out = ''
if (object.constructor == Array){
out += '[\n'
for (var i=0; i<object.length; i++){
out += pad + indent + dump(object[i], pad + indent) + '\n'
}
out += pad + ']'
}else if (object.constructor == Object){
out += '{\n'
for (var i in object){
out += pad + indent + i + ': ' + dump(object[i], pad + indent) + '\n'
}
out += pad + '}'
}else{
out += object
}
return out
}
For anyone checking this question out in 2021 or post-2021
Check out this Other StackOverflow Answer by hassan
TLDR:
JSON.stringify(data,null,2)
here the third parameter is the tab/spaces
This is really just a comment on Jason Bunting's "Use Crockford's JSON.stringify", but I wasn't able to add a comment to that answer.
As noted in the comments, JSON.stringify doesn't play well with the Prototype (www.prototypejs.org) library. However, it is fairly easy to make them play well together by temporarily removing the Array.prototype.toJSON method that prototype adds, run Crockford's stringify(), then put it back like this:
var temp = Array.prototype.toJSON;
delete Array.prototype.toJSON;
$('result').value += JSON.stringify(profile_base, null, 2);
Array.prototype.toJSON = temp;
I thought J. Buntings response on using JSON.stringify was good as well. A an aside, you can use JSON.stringify via YUIs JSON object if you happen to be using YUI. In my case I needed to dump to HTML so it was easier to just tweak/cut/paste PhiLho response.
function dumpObject(obj, indent)
{
var CR = "<br />", SPC = " ", result = "";
if (indent == null) indent = "";
for (var property in obj)
{
var value = obj[property];
if (typeof value == 'string')
{
value = "'" + value + "'";
}
else if (typeof value == 'object')
{
if (value instanceof Array)
{
// Just let JS convert the Array to a string!
value = "[ " + value + " ]";
}
else
{
var od = dumpObject(value, indent + SPC);
value = CR + indent + "{" + CR + od + CR + indent + "}";
}
}
result += indent + "'" + property + "' : " + value + "," + CR;
}
return result;
}
Lots of people writing code in this thread, with many comments about various gotchas. I liked this solution because it seemed complete and was a single file with no dependencies.
browser
nodejs
It worked "out of the box" and has both node and browser versions (presumably just different wrappers but I didn't dig to confirm).
The library also supports pretty printing XML, SQL and CSS, but I haven't tried those features.
A simple one for printing the elements as strings:
var s = "";
var len = array.length;
var lenMinus1 = len - 1
for (var i = 0; i < len; i++) {
s += array[i];
if(i < lenMinus1) {
s += ", ";
}
}
alert(s);
My NeatJSON library has both Ruby and JavaScript versions. It is freely available under a (permissive) MIT License. You can view an online demo/converter at:
http://phrogz.net/JS/neatjson/neatjson.html
Some features (all optional):
Wrap to a specific width; if an object or array can fit on the line, it is kept on one line.
Align the colons for all keys in an object.
Sort the keys to an object alphabetically.
Format floating point numbers to a specific number of decimals.
When wrapping, use a 'short' version that puts the open/close brackets for arrays and objects on the same line as the first/last value.
Control the whitespace for arrays and objects in a granular manner (inside brackets, before/after colons and commas).
Works in the web browser and as a Node.js module.
flexjson includes a prettyPrint() function that might give you what you want.

Categories

Resources