javascript summary function - javascript

im trying to make a small name summary function depending on the size of the elements container, here's what I have;
function shorten_text(str, size){
size = size.match( /[0-9]*/ );
var endValue = Math.floor( Number(size) / 10 );
var number;
var newStr;
for ( number = 0; number <= endValue; number++ ) {
if( str[number].length != 0 ) {
newStr += str[number];
}
}
return newStr + '...';
}
shorten_text('Phil Jackson', '94px');
// output should be 'Phil Jack...'
What I seem to get is undefinedundef...
can anyone see where I am going wrong?
EDIT:
revised code based on comments below for anyone who is googling for such function:
function shorten_text(str, size){
size = parseInt(size);
var endValue = Math.floor(size / 10);
if( str.length > endValue ) {
return str.substring(0, endValue) + '...';
}else{
return str;
}
}
SCREEN SHOT:

You need to initialize your newStr variable with an empty string, otherwise that variable will contain the undefined value, which will be converted to string when you concatenate, e.g.:
var test; // at this moment the variable contains the undefined value
test += 'foo';
// now test contains "undefinedfoo"
In your function:
function shorten_text(str, size){
size = size.match( /[0-9]*/ );
var endValue = Math.floor( Number(size) / 10 );
var number;
var newStr = '';
for ( number = 0; number <= endValue; number++ ) {
if( str[number].length != 0 ) {
newStr += str[number];
}
}
return newStr + '...';
}
shorten_text('Phil Jackson', '94px'); // outputs "Phil Jacks..."
A few comments:
You don't need to call Number(size), since the division operator makes type coercion. implicitly
You could use the substring method to get a portion of your original string.
Accessing characters of a string with the square bracket property accessor may not be supported by some implementations, you can use the standard charAt method (str.charAt(i))
Another approach to do the same:
function shorten_text(str, size){
var endValue = Math.floor(parseInt(size) / 10);
return str.substring(0, endValue) + '...';
}
shorten_text('Phil Jackson', '94px'); // outputs "Phil Jack..." as expected

Related

Undefined in Split String

i have a function to split string into 2 part, front and back. Then reverse it to back and front. Here is my code
function reverseString(string) {
let splitString = ""
let firstString = ""
for(i = 0; i <= string.length/2 - 1; i++) {
firstString += string[i]
}
for(i = string.length/2; i <= string.length; i++) {
splitString += string[i]
}
return splitString + firstString
}
Sorry for bad explanation, this is test case and expected result (first one is expected result, the second one is my result)
console.log(reverseString("aaabccc")); // "cccbaaa" "undefinedundefinedundefinedundefinedaaa"
console.log(reverseString("aab")); // "baa" "undefinedundefineda"
console.log(reverseString("aaaacccc")); // "ccccaaaa" "ccccundefinedaaa"
console.log(reverseString("abcdefghabcdef")); // "habcdefabcdefg" "habcdefundefinedabcdefg"
could you help me, whats wrong with it. Thank you
You could try another approach and use the slice function
function reverseString(string)
{
if (string.length < 2) { return string; }
let stringHalfLength = string.length / 2;
let isLengthOdd = stringHalfLength % 1 !== 0;
if (isLengthOdd) {
return string.slice(Math.ceil(stringHalfLength), string.length + 1) + string[Math.floor(stringHalfLength)] + string.slice(0, Math.floor(stringHalfLength));
}
return string.slice(stringHalfLength, string.length + 1) + string.slice(0, stringHalfLength);
}
console.log(reverseString("aaabccc") === "cccbaaa");
console.log(reverseString("aab") === "baa");
console.log(reverseString("aaaacccc") === "ccccaaaa");
console.log(reverseString("abcdefghabcdef") === "habcdefabcdefg");
A more efficient way to reverse the string would be to split the string, then use the built-in reverse javascript function (which reverses the elements of the split string), and then re-join the elements using the join function.. No need to re-invent the wheel?
You can concatenate the functions in shorthand (.split.reverse.join etc...) so your function would look something like this:
function reverseString(string) {
return string.split("").reverse().join("");
}
Try it out!
function reverseString(string) {
return string.split("").reverse().join("");
}
console.log(reverseString("hello"));
console.log(reverseString("aaabbbccc"));
If there's a particular reason you're opting not to use the in-built functions (i.e. if I've missed something?) , feel free to comment.
The short version of what you need:
function reverseString(string) {
const splitPosition = Math.ceil(string.length / 2);
return string.substring(splitPosition) + string.substring(0, splitPosition);
}
The key to your question is the middle element. To accomplish that, you probably want to use Math.floor that round under.
console.log(reverseString("aaabccc")); // "cccbaaa"
console.log(reverseString("abcdefghabcdef")); // "habcdefabcdefg"
function reverseString (str) {
if (str.length<2) {
return str
}
var half = Math.floor(str.length / 2);
return (str.slice(-half) + (str.length%2?str[half]:"") + str.slice(0,half));
}
reverseString('')
> ""
reverseString('1')
> "1"
reverseString('12')
> "21"
reverseString('123')
> "321"
reverseString('1234')
> "3412"
reverseString('12345')
> "45312"
reverseString("aaabccc")
> "cccbaaa"
reverseString("abcdefghabcdef")
> "habcdefabcdefg"
So basically your problem is not to grab 2 parts of the string and rearrange, it is to grab 3 parts.
1 part: str.slice(0,half)
2 part: str.length%2 ? str[half] : ""
3 part: str.slice(-half)
The second part is empty if the string length is even and the middle character if is odd.
So the code version in long self explanatory code:
function reverseString (str) {
if (str.length<2) {
return str
}
var half = Math.floor(str.length / 2);
var firstPart = str.slice(0,half);
var midlePart = str.length % 2 ? str[half] : ""; // we could expand also this
var endPart = str.slice(-half);
return endPart + midlePart + firstPart;
}
And also, notice the precondition, so I don't have to deal with the easy cases.
Also, in your code, you got undefined because you access in the last loop to:
string[string.length] you need to change <= by <

How can I give an input field a format?

Everytime the user presses a button I want every 3 characters to add a dot, example:
123
123.456
12.345.678
I want this to happend everytime the key is pressed, this is what I have but no luck...
function format_num(input) {
str = input.value;
str.replace(/(.{3})/,'$1.')
input.value = str;
}
<input type="text" name="num" id="num" onKeyPress="format_num(this)">
First off, you are missing a semicolon after your regex. Second, you have to add the g modifier to find all the matches rather than stopping at the first one. Also, assign the result of the .replace() to a variable, even str itself.
str = str.replace(/(.{3})/g,"$1.");
This is because in Javascript strings are immutable: this means that all the String method do not actually change the contents string, but return a new modified string.
One last caveat: you will notice that, as you add the dots, this regex will not work anymore, as you will be adding dots in between dots.
You have to avoid counting the dots in your string. You might do so by reworking your variable before executing the Regex; something on this line:
str = str.split('.').join('');
Working example
You have to scan from right to left. A more readable (compared to Utkanos) solution is
function format_num(input) {
var inStr = input.value.replace(/\./, '');
var outStr = '';
for (var count=0, i=inStr.length-1; i>=0; i--, count++ ) {
if ( count && count % 3 == 0 ) outStr = '.' + outStr;
outStr = inStr.charAt(i) + outStr;
}
input.value = outStr;
}
This is the most horrible, unreadable answer I've ever posted but it does work, for any number.
var num = 12345678;
var formatted = num.toString().replace(/./g, function(num) { return num+'|'; }).split('|').reverse().join('').replace(/\d{3}/g, function(nums) { return nums+'.'; }).replace(/./g, function(num) { return num+'|'; }).split('|').reverse().join('').replace(/^\./, '');
Generates 12.345.678
I found this script that works perfectly!! I had some issues with the answers so I looked and came up with this piece of work...Thanks anyways!!
function formatNumber( originalValue ){
originalValue = ( originalValue != null ? originalValue.toString() : "0" );
var nStr = originalValue.replace( /\./g, "" );
var jj=0;
var leftNumbers = 0;
var x = nStr.split(',');
var x1 = x[ 0 ];
var x2 = x.length > 1 ? ',' + x[ 1 ] : '';
var rgx = /(\d+)(\d{3})/;
while( rgx.test( x1 ) ){
x1 = x1.replace( rgx, '$1' + '.' + '$2');
}
nStr = x1 + x2;
for( jj=0; leftNumbers>0; jj++ ){
if( /[0-9]/.test( nStr.toString().substring( jj, ( jj + 1 ) ) ) )
leftNumbers--;
}
if( originalValue == nStr )
return originalValue;
return nStr;
}

trim Array in JS

I Have an array say
['(','C','1','2',')']
Now I want to trim data from array beginning from indexOf('C') + 2 ,If it is a digit I need to remove it from array.. So for the above example final array has to be
['(','C','1',')']
For example if I have ['(','C','1','2','3','*',')'] I want it to be trimmed to ['(','C','1','*',')'] , After element 'C' only one numeral is allowed.
I know I can traverse the array by getting the indexOf('C') and then checking each element for numeric.. but help me with some efficient and better way. like using splice or something.
If the position from where you want to 'trim' is known, you could use filter here, like.:
var a = ['(','C','1','2','3','*',')']
.filter( function(a){
this.x += 1;
return this.x<=2 ? a : isNaN(+a);}, {x:-1}
);
Which could lead to this Array extension:
Array.prototype.trimNumbersFrom = function(n){
return this.filter( function(a){
this.x += 1;
return this.x<=n ? a : isNaN(+a);
}, {x:-1}
);
};
//=> usage
var a = ['(','C','1','2','3','*',')'].trimNumbersFrom(2);
//=> ["(", "C", "1", "*", ")"]
See also ...
var a = ['(','C', 'a', '8','2',')'].join("").split("C");
var nPos = a[1].search(/[0-9]/g);
var firstNumber = a[1][nPos];
var b = a[1].split(n);
// rebuild
a = a[0] + "C" + b[0] + firstNumber + b[1].replace(/[0-9]/g, "");
Not tested thoroughly but for your case it works.
You can use of isNaN() function which returns false if its a valid number or true if it's not a number
var str = ['(','C','1','2','3','4','*',')']; // Your Input
var temp = [],count = 0;
for(var i=0;i<str.length;i++)
{
if(i<str.indexOf('C') + 2)
{
temp[count] = str[i];
count++;
}
else
{
if(isNaN(str[i]) == true)
{
temp[count] = str[i];
count++;
}
}
}
str = temp;
alert(str);
LIVE DEMO

Javascript multiple digit index

I have searched around the net and the solution must be so simple no one has asked?
I just wanted to use an index like + i + to return 001, 002, 003, etc
How about
('000' + i).substr(-3);
So something like this?
function number_pad(num,len) {
num = ""+num;
while(num.length < len) num = "0"+num;
return num;
}
// Usage: number_pad(i,3);
Alternatively, extend the native object:
Number.prototype.pad(len) {
var num = ""+this;
while(num.length < len) num = "0"+num;
return num;
}
// Usage: i.pad(3);
For future reference, this is called zerofill or zero-padding.
function paddedNumber(n) {
// A string containing the fully padded zero value.
var zeroes = "000";
// The number as a string.
var numstr = "" + n;
var nDigits = numstr.length;
// Keep any sign at the front.
var sign = "";
if (/^[\+\-]/.test(numstr)) {
sign = numstr.charAt(0);
numstr = numstr.substring(1);
}
// Concatenates the number with just enough zeroes.
// No padding if itoa is already longer than the pad.
return sign + zeroes.substring(nDigits) + numstr;
}

JQuery/JavaScript increment number

I am trying to increment a number by a given value each second and retain the formatting using JavaScript or JQuery
I am struggling to do it.
Say I have a number like so:
1412015
the number which this can be incremented by each second is variable it could be anything beween 0.1 and 2.
Is it possible, if the value which it has to be incremented by each second is 0.54 to incremenet the number and have the following output:
1,412,016
1,412,017
1,412,018
Thanks
Eef
I'm not quite sure I understand your incrementation case and what you want to show.
However, I decided to chime in on a solution to format a number.
I've got two versions of a number format routine, one which parses an array, and one which formats with a regular expression. I'll admit they aren't the easiest to read, but I had fun coming up with the approach.
I've tried to describe the lines with comments in case you're curious
Array parsing version:
function formatNum(num) {
//Convert a formatted number to a normal number and split off any
//decimal places if they exist
var parts = String( num ).replace(/[^\d.]-/g,'').split('.');
//turn the string into a character array and reverse
var arr = parts[0].split('').reverse();
//initialize the return value
var str = '';
//As long as the array still has data to process (arr.length is
//anything but 0)
//Use a for loop so that it keeps count of the characters for me
for( var i = 0; arr.length; i++ ) {
//every 4th character that isn't a minus sign add a comma before
//we add the character
if( i && i%3 == 0 && arr[0] != '-' ) {
str = ',' + str ;
}
//add the character to the result
str = arr.shift() + str ;
}
//return the final result appending the previously split decimal place
//if necessary
return str + ( parts[1] ? '.'+parts[1] : '' );
}
Regular Expression version:
function formatNum(num) {
//Turn a formatted number into a normal number and separate the
//decimal places
var parts = String( num ).replace(/[^\d.]-/g,'').split('.');
//reverse the string
var str = parts[0].split('').reverse().join('');
//initialize the return value
var retVal = '';
//This gets complicated. As long as the previous result of the regular
//expression replace is NOT the same as the current replacement,
//keep replacing and adding commas.
while( retVal != (str = str.replace(/(\d{3})(\d{1,3})/,'$1,$2')) ) {
retVal = str;
}
//If there were decimal points return them back with the reversed string
if( parts[1] ) {
return retVal.split('').reverse().join('') + '.' + parts[1];
}
//return the reversed string
return retVal.split('').reverse().join('');
}
Assuming you want to output a formatted number every second incremented by 0.54 you could use an interval to do your incrementation and outputting.
Super Short Firefox with Firebug only example:
var num = 1412015;
setInterval(function(){
//Your 0.54 value... why? I don't know... but I'll run with it.
num += 0.54;
console.log( formatNum( num ) );
},1000);
You can see it all in action here: http://jsbin.com/opoze
To increment a value on every second use this structure:
var number = 0; // put your initial value here
function incrementNumber () {
number += 1; // you can increment by anything you like here
}
// this will run incrementNumber() every second (interval is in ms)
setInterval(incrementNumber, 1000);
This will format numbers for you:
function formatNumber(num) {
num = String(num);
if (num.length <= 3) {
return num;
} else {
var last3nums = num.substring(num.length - 3, num.length);
var remindingPart = num.substring(0, num.length - 3);
return formatNumber(remindingPart) + ',' + last3nums;
}
}
function rounded_inc(x, n) {
return x + Math.ceil(n);
}
var x = 1412015;
x = rounded_inc(x, 0.54);

Categories

Resources