Changing values of each object in Javascript - javascript

What is the best way to add the additional path information to each javascript object? Like "assets/img/upload/" before each jpg name? That I have url="assets/img/upload/02.jpg" etc.? That would be great help!
My data right now:
[Object { url="02.jpg"},
Object { url="03.jpg"},
Object { url="09.jpg"},
Object { url="04.jpg"},
Object { url="5.jpg"}
...]

A simple for loop:
for(var i = 0; i < array.length; i++)
{
array[i].url = "assets/img/upload/" + array[i].url;
}

Suppose your array of objects is called MyArray:
for (var i = 0, LoopTimes = MyArray.length; i < LoopTimes; i++) {
MyArray[i].url = "assets/img/upload/" + MyArray[i].url;
}
Note that:
a) the opening curly brace goes on the same line as the for statement. See Crokfod on Javascript The Good Parts on youtube for the explanation. In javascript, putting the opening brace on the next line can create some weird bugs that are hard to detect.
b) I cache the length of MyArray in LoopTimes so that I don't have to evaluate the length of the array at every iteration.

If you are only going to be running this code in a modern browser, you could always consider using the map method of the Array object.
Assuming your array of objects is called "array"
array.map(function(item) {return item.url = "assets/img/upload/" + item.url;});
This runs the anonymous function, that takes an "item" in the array, and returns the modified url field, over each element of the array.
If you need your code to run on older browsers, stick with the for loops suggested by the other contributors.

Related

get string from an array?

trying to loop on string array but it throws error foreach is not a function what is correct way to implement using typescript ?
main.ts
content = ["renewel","payments"]
if i do for loop
for (let i = 0, len = content.length; i < len; i++) {
console.log(content[i]);
}
it prints all indexs [r e n e etc
if do foreach
content.forEach(function(content){
console.log(content);
})
it throws error content.forEach is not a function
Your code works just fine; it's very likely you've mutated content's type in some way at some point in your code. Ensure any functions you may be passing it (content) to aren't mutating the original array.
You might also consider using newer syntax, like:
content.forEach(item => {
console.log(item);
});
or even
content.forEach(item=> console.log(item));
Two small things, by the way; there's no need to cache length in a for loop (JS engine does that for you), and I don't know if it matters or not... but you've misspelled 'renewal' ;)

Run the same function on each item in a list / array

Goal
I have a working function (JSFiddle). On numerous occasions throughout a script the function runs sequentially. In these instances, there is a lot of repetitious code that I would like to consolidate.
Ideally changing code like this:
functionName("First_item") +
functionName("Second_item") +
functionName("Third_item") +
To something like this:
functionName("First_item", "Second_item", "Third_item");
The function will run for each item in the list so the result is the same but the code more elegant and maintainable.
Notes:
I’m not looking to use any libraries (e.g. jQuery) to accomplish the goal.
Solution
Amit Joki’s answer kindly noted I could use arguments. When I implemented the code, the modified function (JSFiddle) only returned the output string for the first argument / item.
Vanice’s answer pointed out the eventual solution.
Make one string from the output of all arguments / items by concatenating (joining) the output strings within the for loop (with the use of +=).
Return the concatenated output by placing the return outside of the for loop.
Example
Working solution (JSFiddle).
Thanks
Thank you very much to everyone for their time and help on this. I really appreciate it!
Leveraging Javascript's Prototype OOP: You can add an each function to Array's themselves, so every array in your code that will automatically have an inhereted each function.
Array.prototype.each = function(callback){
for (var i = 0; i < this.length; i++){
callback(this[i]);
}
}
Usage:
myArray.each(myCoolFunction)
['something','somethingelse',somethingother'].each(myCoolFunction)
myArray.each( function (item) {
// if your item has a method
item.Something();
// if you'd like to call a function on the item:
doSomething(item);
});
caveats:
Because javascript is an asynchronous language that is interpreted differently across various browsers and inherently handles primitive objects and complex objects differently, it is highly recommended usage of underscore or lodash. You can also make your own, but you'll need ensure the objects passed through will be handled by the functions properly. This may include workarounds or creating special callback functions for different object types that are passed through your each function.
For more information: Is JavaScript a pass-by-reference or pass-by-value language?
Libraries you should seriously consider:
lodash:
https://lodash.com/docs#forEach
_([1, 2, 3]).forEach(function(num) { console.log(num); }).join(',');
// → logs each number and returns '1,2,3'
_.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); });
// → logs each number and returns the object (property order is not guaranteed across environments)
underscore:
http://underscorejs.org/#each
_.each([1, 2, 3], alert);
=> alerts each number in turn...
You don't need an array. Just use arguments
function functionName(){
for(var i = 0; i < arguments.length; i++){
// do something with arguments[i];
}
}
and then you can do
functionName("shot_type","shot_height","shot_angle","framed","scene_depth");
P.S #codebox's solution works if supporting legacy IE version isn't a problem. Don't know why he deleted it...so putting it here so it helps. His answer using forEach
["shot_type","shot_height","shot_angle","framed","scene_depth"].forEach(FunctionName);
EDIT: Looking at your Fiddle, you have a return inside the for loop - therefore the function will return after the first iteration. Put the return after the for and concatenate the output to one string.
var output = "";
for(...){
output += description_of_object + ": " + randomly_selected_item_from_object + ".\n";
}
// return it
return output;
With Javascript only:
var actions = ["shot_type","shot_height","shot_angle","framed","scene_depth"];
for (var i = 0; i < actions.length; i++){
FunctionName(actions[i]);
}
With JQuery:
$.each(["shot_type","shot_height","shot_angle","framed","scene_depth"], function(index,value){
FunctionName(value);
});
I haven't tested it but it should work.
To avoide redundancy in code use an array with the values, that you want to pass through the function and call the function in an loop.
var vals=["shot_type","shot_height","shot_angle","framed","scene_depth"];
for(var i=0; i<vals.length; i++)
{
FunctionName(vals[i]);
}
If you want to expand the function (adding another parameter) you can just expand the for-loop and the array structure.
Alternatively you could fill an object with the values and handle this logic in an object. But this would just do a difference on calling the function.

Searching an array for values ending in certain characters in JavaScript

So Im looking for help for writing a simple function in javascript. What I am trying to do is create an array of 6 name and print only those ending in "ie" or "y".
Here is my code - any help is appreciated. It unfortunately never reaches the function :(
//An array of names
var nameList = new Array("Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin");
//Prints names before searching
document.write(nameList);
function e_names(nameList) {
for (var index = 0; index < arrayList.length; index++) {
var name = arrayList[index];
if (name == /\bie\b/ || name == /\by\b/)
document.write("",name, " </ br>");
index++;
} //End of for loop
} //End if method
Use /(ie|y)$/ ($ is used to match the end) to test it:
if (/(ie|y)$/.test(name))
It unfortunately never reaches the function :(
In your code, you are defining a function but then never executing it. Execute it like so:
e_names(namesList);
The loop has a bug:
for (var index = 0; index < arrayList.length; index++) {
arrayList is not defined, at least not in this code. It could be a previously defined or global variable, but then why does the function take a parameter called nameList? I think this is a simple typo.
if (name == /\bie\b/ || name == /\by\b/)
I am not sure what it means to equal a regular expression, but I would hazard a guess it won't do what you want. I think you want the .test function such as:
if (/\bie\b/.test(name) || /\by\b/.test(name))
Your pattern includes \b, the word boundary both before and after the y or ie. Therefore, it will only match strings that have i or ie as exact strings or with spaces around them. They won't match array or key or cookie. I think you meant to anchor them to end of string as suggested by #xdazz's answer. He even OR'ed the two expressions together for you:
if (/(ie|y)$/.test(name))
Finally, you double-increment index:
index++;
This will only iterate over "Freddie", "Thomas", and "Terry" because you increment twice. The index++ at the end of the loop construct is sufficient. Take this line out.
Altogether now:
//An array of names
var nameList = [ "Freddie", "Mary", "Thomas", "Suzie", "Terry", "Kevin" ];
//Prints names before searching
document.write(nameList);
function e_names(names) {
for (var index = 0; index < names.length; index++) {
var name = arrayList[index];
if (/(ie|y)$/.test(name)) {
document.write("",name, " </ br>");
}
} //End of for loop
} //End if method
e_names(nameList);
Note that I renamed the parameter so that it doesn't cause confusion with scoping and I also put curly braces around your if block. I usually don't change other people's code style, but I felt it was needed in this case to make it clearer.
I also changed the array construction to use the literal notation. Much debate has been had around the new Array constructor. It's probably safe for this example, but if there is a single element or the array contents are dynamic, it gets confusing. For example, what does new Array(17) mean? It means create an array with 17 null references in it. It does not create an array with the number 17 in it. For that reason, my advice is to use the [ ] syntax. For details, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array

Javascript .pop() and .sort() not working right in a for loop

I'm trying to remove the last element in the array but it ends up putting the removed element back to the top of the list and some of the other elements are listed differently.
Same thing using the .sort() method. The output shows this sentence five times:
Tolstoy wrote War and Peace,Twain wrote Huckleberry Finn
var author_title = new Array(5)
author_title[0]="Tolstoy wrote War and Peace";
author_title[1]="Twain wrote Huckleberry Finn";
author_title[2]="Hardy wrote The Return of the Native";
author_title[3]="Dickens wrote A Christmas Carol";
author_title[4]="Uris wrote Exodus";
for(var count=0;count<author_title.length;count++) {
document.write(author_title.pop() + "<br>");
}
for(var count=0;count<author_title.length;count++) {
document.write(author_title.sort()+"<br>");
}
If you wanted to alter your array then use pop, writing a variable that is equivalent to array.length outside of the for loop, then setting your variable to that declared variable. You have to remember that you are changing your array every time you .pop(), thus changing the for-loop in each iteration. Also, the <br /> is for HTML so you may have just forgotten your self-closing tag on that
var length = array.length;
for( var i = 0; i > length; i++ ) {
document.write( array.pop() + "\n")
}
No part of this should work. for..in loops iterate over the keys for each properly, not the values. It's not meant for iterating over arrays. On my machine, it produces 0,1,2,etc.
You're also attempting to pop elements while iterating over the array. pop modifies the array, so your iterator will be invalidated on each iteration.
What you want is a simple for loop:
for (var i = 0; i < author_title.length; ++i) {
console.log(author_title[i]);
}

Strange behavior in Javascript enhanced for...in loop

I am making a Javascript game with the canvas tag, and I am using an enhanced for loop to update the player positions.
In brief:
var actors = new Array();
var player = new Actor(0, 0, img);
actors[0] = player;
function update_positions() {
//position 1
for(var a in actors) {
//position2
a.xpos += a.xvel;
a.ypos += a.yvel;
}
}
Just outside of the for loop at position 1, I can access the correct value of actors[0].xvel. Inside the for loop at position 2, a.xvel is undefined. Can someone explain to me what is happening?
The for...in statement is meant to be used to iterate over object properties, by looking your code seems that actors is an Array (you are setting the initial element with index 0).
This statement will also crawl up the prototype chain, if you have extended the Array.prototype those properties will be iterated, and also the order of iteration is not warranted.
I would recommend you to avoid problems and iterate using a normal for loop:
for (var i = 0; i < actors.length; i++) {
actors[i].xpos += actor.xvel;
actors[i].ypos += actor.yvel;
}
If I'm wrong, and actors is not an Array, I would recommend you to use the hasOwnProperty method, to ensure that the property exists in the object itself, not up somewhere in the prototype chain:
for (var name in object) {
if (object.hasOwnProperty(name)) {
//
}
}
it looks like you're trying to access object properties on the name, not the value here. the index, in this case '0', gets assigned to 'a' in the for/in loop.
what you want to do is access the value of the array member, ie: actors[a].
try this:
for(var a in actors) { // a=0 the first time around the loop,
actor = actors[a]; // same thing as actors[0];
actor.xpos += actor.xvel;
actor.ypos += actor.yvel;
}
The for (x in y) construct iterates through the indexes of an array, not its members.
Try using actors[a].xpos instead of just a.xpos.
See here for more info on JavaScript for-in loops.
Another option is to use the underscore library:
_.each( actors, function(a) {
a.xpos += a.xvel;
a.ypos += a.yvel;
});
or if you don't want to use underscore but are using JQuery anyway, then you can do:
$.each( actors, function(i, a) {
a.xpos += a.xvel;
a.ypos += a.yvel;
});
One nice feature of this functional pattern of iteration is that you can use var to declare variables in the loop that are scoped to the body of the loop, which helps avoid getting bitten by the odd variable scoping rules of JavaScript.

Categories

Resources