How to prepend a string using 'this' - javascript

Say I have an array of strings. And I want to prepend each of these strings with a fixed (common) string. I know that in Javascript, strings can be concatenated like strM = str1 + str2 + str3 + ... + strN or strM = concat(str1, str2, str3, ..., strN). Consider this piece of code.
var defImgDirPath = 'res/img/';
$([
'home-icon-dark.png',
'home-icon-light.png'
]).each(function() {
/*
* Prepend each string with defImgDirPath
*/
});
Now I can't do this = defImgDirPath + this; (I was stupid enough to try)
Also, I tried return (defImgDirPath + this); but that wouldn't work either.
I am thinking something along the lines of a function like this.prependString(defImgDirPath); but does such a function exist? If not, how do I write one?
Note: I know it can be done much easily and simply with a for loop too, but what's the fun in that? :)

var defImgDirPath = 'res/img/';
var images = [
'home-icon-dark.png',
'home-icon-light.png'
];
$(images).each(function(idx, val) {
images[idx] = defImgDirPath + val;
});
console.log(images);

In latest standards of javascript (ECMA 5), You can do this without jquery:
var defImgDirPath = 'res/img/';
['home-icon-dark.png','home-icon-light.png'].map(function(i) {
return defImgDirPath + i; });
EDIT : Besides, map function of jquery works similar too.

The problem is that you are changing a copy of the item in the array, so the array will be unaffected.
Loop through the indexes in the array and put the result back in the array:
var arr = [ 'home-icon-dark.png', 'home-icon-light.png' ];
for (var i = 0; i < arr.length; i++) {
arr[i] = defImgDirPath + arr[i];
}
If you really want to use a loop method from jQuery, then you would need to use map, so that you get the result as an array. Note that you need to use the parameters of the callback function, as this is not the item from the array:
arr = $.map(arr, function(str){
return defImgDirPath + str;
});

In Javascript, this always refers to an object (the current context object), so it won't ever be a string, and therefore trying to concatenate it with another string will fail, as you've found.
However, there's no need to use jQuery or objects for what you're doing; you're just prepending a known value to the start of each of an array of strings.
Let's rewrite it using standard Javascript, without the jQuery complications...
var defImgDirPath = 'res/img/';
var images = [
'home-icon-dark.png',
'home-icon-light.png'
];
for(var count=0; count<images.length; count++) {
images[count] = defImgDirPath + images[count];
}
I've put the images array into a variable to make it easier to see what the actual loop code is doing. As you can see, it's a pretty simple loop; no need for jQuery magic here.
hope that helps.

this.prependString(defImgDirPath);
No. Strings are immutable in JavaScript. Concatenation to a new string would be fine, and using .concat it would look like
var newString = defImgDirPath.concat(this); // no static function!
If not existing, how do I write one?
You can't, as assigning object to "this" is impossible.
Instead, you have to assign to a property of the array you're working on (using the static $.each instead of working on a collection):
var arr = [
'home-icon-dark.png',
'home-icon-light.png'
];
$.each(arr, function(i) {
arr[i] = defImgDirPath + this;
});
arr[0] // res/img/home-icon-dark.png
Also I tried return (defImgDirPath + this);
You would need to use map for that, creating a new array:
var arr = $.map([
'home-icon-dark.png',
'home-icon-light.png'
], function(str) {
return defImgDirPath + str;
});
Of course, it might be easier without jQuery at all:
for (var i=0; i<arr.length; i++) {
arr[i] = defImgDirPath + arr[i];
}
And also map is available as a native function (not in outdated browsers):
var arr = [
'home-icon-dark.png',
'home-icon-light.png'
].map(function(str) {
return defImgDirPath + str;
});

Related

How to convert a converted string back into an array?

As far as I know, you can only save strings to local storage. So, I had to write a function so that I could save arrays. If I call console.log(fixA(["string1", [5, [false]], "string2"])); I get an output of "'string1',[5,[false]],'string2'". Here it is:
function fixA(array) {
var toreturn = "";
for (var i = 0; i < array.length; i++) {
if (typeof array[i] === 'object') {
toreturn += "[" + fixA(array[i]) + "]";
} else {
if (typeof array[i] === 'string') {
toreturn += "'" + array[i] + "'";
} else {
toreturn += array[i];
}
}
if (i < array.length - 1) {
toreturn += ",";
}
}
return toreturn;
}
console.log(fixA(["string1", [5, [false]], "string2"]));
The issue now is that I have no clue how to convert it back. I've tried a few things but have always gotten stuck on how I convert the arrays back. This is basically what I've tried:
function fixS(string) {
var toreturn = [];
var temp = string.split(",");
for (var i = 0; i < temp.length; i++) {
// I could run a check here to see if temp[i] starts with "[", but I'm not sure how to tell where the array ends.
// If it is an array, then I'd need to pass everything inside of the array back into fixS, making it recursive.
// The times I tried to do those two things above, I ran into the issue that the commas inside of the sub arrays also split everything, which I don't want (as the recursive function will deal with that).
toreturn.push(temp[i]);
}
return toreturn;
}
console.log(fixS("'string1',[5,[false]],'string2'"));
// This also doesn't return numbers as numbers or booleans as booleans.
Not much there, but it's as far as I've gotten. Any help is appreciated.
Instead of doing your own bespoke solution, unless you have something that can't be represented in JSON (your example can be), use JSON:
On page load:
var data = JSON.parse(localStorage.getItem("data") || "null");
if (!data) {
// There wasn't any, initialize
}
or
var data = JSON.parse(localStorage.getItem("data") || "{}");
...if you want a blank object if there is nothing in local storage.
When saving your data:
localStorage.setItem("data", JSON.stringify(data));
As David said there's JSON.stringify() & JSON.parse();
you can use those methods :
function save_to_storage(id, anything){
localStorage.setItem(id, JSON.stringify(anything));
}
function load_from_storage(id){
return JSON.parse(localStorage.getItem(id));
}
It can be achieved with help of JSON.stringify and JSON.parse functions.
Let me explore with help of code snippet.
var original_arr = ["string1", [5, [false]], "string2"]; // array
// Converting this array into string
var converted_str = JSON.stringify(original_arr); // converted into string
// Converting this string back to array
var new_arr = JSON.parse(converted_str ); // back to array
The other answers have already covered it, but note that P5.js also provides functionality for working, saving, and loading JSON directly.
Take a look at the saveJSON() and loadJSON() functions in the reference.

converting string array into a key value pair object

I am getting an output which looks like this
var x = ["title: x_one", " description: 1", " value: 4"]
where x[0] returns title: x_one
Which is a string. I cant read the property of title. How would I convert it into an object so that eventually I will be able to loop through the array and read the properties such as title, description and value.
I am trying to do this through jquery
I have been looking for a solution but havent really found one. If there is any out there which I am missing I would highly appreciate if anyone else have and could point me to that
Loop through your array, splitting the values at the : character. Then use the first part as a property name, the second part as the value, in an object.
var obj = {};
for (var i = 0; i < x.length; i++) {
var split = x[i].split(':');
obj[split[0].trim()] = split[1].trim();
}
Try this function I have already tested it
var a=new Array();
for(var i=0;i<x.length;i++){
var tmp=x[i].split(":")
a[tmp[0]]=tmp[1]
}
A more up to date version that that uses some newer language
const splitStr = (x) => {
const y = x.split(':');
return {[y[0].trim()]: y[1].trim()};
}
const objects = ["title: x_one", " description: 1", " value: 4"].map(splitStr)
console.log(objects)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
http://www.ecma-international.org/ecma-262/6.0/#sec-object-initializer
Assuming you have an object before you create this array you don't need to convert this to anything. Using jQuery's each you can get the value and the key.
$.each( obj, function( key, value ) {
alert( key + ": " + value );
});
If this is the final output then you can just use String.prototype.split when you loop through.
Just bumped into this. Here is another solution for OP's original array.
var x = ["title: x_one", " description: 1", " value: 4"]
function mapper(str)
{
var o = {};
strArr = str.split(":");
o[strArr[0].trim()] = strArr[1].trim();
return o;
}
var resultArray = x.map(mapper);
console.log(resultArray[0].title);
console.log(resultArray[1].description);
console.log(resultArray[2].value);
fiddle

How to get index of an array element which has more than one sub elements in javascript

I am working in javascript and I would like to find the index of an element in an array .
var task = [{taskno:'1',todo:'cooking'},{taskno:'2',todo:'play'}];
now i want to find the index of task which has todo as cooking and i dont know its task no .... is there any inbuilt function ?
I have tried this code but It's not working:
var index = task.indexOf(todo:'cooking');
Now I'm using a for loop is there any other way?
Thanks in advance :)
indexOf will give you the index of an object in an array, but you must already have a reference to that object.
e.g.
var o1 = { val: 'o1' },
o2 = { val: 'o2' };
[o2, o1].indexOf(o1); //1
If you do not have a reference to the object, you will have to create your own search algorithm.
var tasks = [{taskno:'1',todo:'cooking'}, {taskno:'2',todo:'play'}];
var index = indexOfFirstMatch(tasks, function (task) {
return task.todo === 'cooking';
});
console.log(index); //0
function indexOfFirstMatch(arr, matcher) {
var i = 0, len = arr.length;
for (; i < len; i++) {
if (matcher(arr[i])) return i;
}
return -1;
}
If you need the actual object, vs. just it's index. You could use the underscore library and it's findWhere function:
var task_wanted = _findWhere(task, {todo: "Cooking"});
If you actually need the index, then use task_wanted to search the array with indexOf().

sum index in JavaScript foreach

In the following code sample i get a strange behavior
var data = ['xxx', 'yyy'];
for (var i in data)
{
var a = i;
var b = data[i];
}
The two first iterations works just fine. I get index "0" and "1" in i, but then it loops one extra time and now the i is "sum". Is this by design or what is this extra iteration used for? The result in my case is always empty and it messes up my code. Is there a way to not do his extra loop?
BR
Andreas
It looks like you (or some other code you've included) have added extra properties onto the Array prototype. What you should be doing is checking to see whether the object you're iterating over actually has that property on itself, not on its prototype:
for (i in data) {
if (data.hasOwnProperty(i)) {
a = i;
b = data[i];
}
}
That said, you should never use for .. in on arrays. Use a regular for loop.
See here for more information: http://yuiblog.com/blog/2006/09/26/for-in-intrigue/
You are looping through an Array, not through an Object. For arrays it's better to use:
for (var i=0; i<data.length; i=i+1){
/* ... */
}
In your loop every property of the Array object is taken into account. That makes the for ... in loop for array less predictable. In your case it looks like sum is a property (method) that's added to Array.prototype elsewhere in your code.
There are more ways to loop through arrays. See for example this SO-question, or this one
Just for fun, a more esoteric way to loop an array:
Array.prototype.loop = function(fn){
var t = this;
return (function loop(fn,i){
return i ? loop(fn,i-1).concat(fn(t[i-1])) : [];
}(fn,t.length));
}
//e.g.
//add 1 to every value
var a = [1,2,3,4,5].loop(function(val){return val+1;});
alert(a); //=> [2,3,4,5,6]
//show every value in console
var b = [1,2,3,4,5].loop(function(val){return console.log(val), val;});
Here's a way to safely iterate.
var data = ['xxx', 'yyy'];
for (var i = 0; i < data.length; i++)
{
var a = i;
var b = data[i];
}
What you are getting is an method coming from extending the Array object, I guess you are using some library where is something like
Array.prototype.sum = function () {...};
Perhaps setting data like this would work better: var data = {0:'xxx', 1:'yyy'};
First of all data is an object. Try to add console.log(a); and console.log(b); inside your loop and you'll see.

JavaScript Array / Struct

I would like to create a structure within javascript. I have a pair of informations, I would like to use, example:
array[1] = new Struct();
array[1].name = "parameter-name";
array[1].value = "parameter-value";
array[2] = new Struct();
array[2].name = "parameter-name2";
array[2].value = "parameter-value2";
This can be on a diffrent page with diffrent values, maybe on element within my array, maybe 2-20..
Later, within my generic javascript, I would like to parse the array and continue with my parameters, example:
for(i=1 to length_of_my_array) {
_tag.array[i].name = array[i].value;
}
How can I realize this with pure javascript? Thanks for any hint!
As long as you don't want any fancy features, it's really easy to create such structures in JavaScript. In fact, the code you posted will almost work, if you replace the new Struct() with this:
array[1] = {};
This creates an empty object, and you can put any properties you want in it, such as name and value.
To create an array, you can do something like this:
var array = []; // empty array
// object literal notation to create your structures
array.push({ name: 'abc', value: 'def' });
array.push({ name: 'ghi', value: 'jkl' });
...
And to iterate over the array:
for (var i = 0; i < array.length; i++) {
// use array[i] here
}
It would be good to find out more regarding the problem you are attempting to resolve.
I don't think there is an object in JavaScript called Struct, unless you define one.
I think what you are looking for is a JavaScript object instead of Struct. There are a number of ways to create a new object, and they can be nested in an array or in other objects.
myArray[0] = new Object();
myArray[0].name = "parameter-name";
myArray[0].value = "parameter-value";
myArray[1] = new Object();
myArray[1].name = "parameter-name2";
myArray[1].value = "parameter-value2";
Notice that I have changed your code in a couple of ways:
1. "array" is named "myArray" to clarify that we are referring to a particular array.
2. The first instance of myArray is 0. Arrays start at 0 in Javascript.
3. Struct is changed to Object.
myarray = [
{
"name":"parameter-name",
"value":"parameter-value"
},
{
"name":"parameter-name2",
"value":"parameter-value2"
}
];
This is an alternative syntax for doing the same thing. It uses "literal notation" to designate an array (the square brackets), and the objects (the curly brackets).
for(var i = 0; i < myArray.length; i++) {
for(key in myArray[i]) {
alert(key + " :: " myArray[i][key]);
}
}
This will loop over the array and alert you for each property of the object.
alert(myArray[0]['value']) //parameter-value
myArray[0]['value'] = "bar";
alert(myArray[0]['value']) //bar
Each property of each object can also be assigned a new value.
You can define arrays and generic objects in pure JavaScript/json:
var array = []; // empty array
array.push({name: 'parameter-name', value: 'parameter-value'});
array.push({name: 'parameter-name2', value: 'parameter-value2'});
console.log(array);
// Output:
// [Object { name="parameter-name", value="parameter-value2"}, Object { name="parameter-name2", value="parameter-value2"}]
You can also define the same array like so:
var array = [
{name: 'parameter-name', value: 'parameter-value'},
{name: 'parameter-name2', value: 'parameter-value2'}
];
As far as looping through the array:
for (var i = 0; i<array.length; i++) {
var elem = array[i];
console.log(elem.name, elem.value);
}
// Outputs:
// parameter-name parameter-value2
// parameter-name2 parameter-value2
I'd store object literals in the array, like so:
var myArray = [];
myArray[0] = {name:"some name", value:"some value"};
myArray[1] = {name:"another name", value:"another value"};
for (i=0; i < myArray.length; i++) {
console.log(myArray[i].name + ' / ' + myArray[i].value);
}
// initialize empty array
var myArray = [];
// fill it with an object - the equivalent of a struct in javascript
myArray.push({
name: 'example-name'
value: 'example-value'
});
// repeat as neccessary
// walking through the array
for (var i = 0; i < myArray.length; i++)
{
// retrieving the record
record = myArray[i];
// and accessing a field
doSomething(record.name);
}
var array = {paramName: 'paramValue', paramName2: 'paramValue2'};
for(i in array) {
_tag.i = array.i;
}
There is no "Struct" in JavaScript only Object
my_array = new Array();
my_array.push({name: 'john', age:31});
my_array.push({name: 'da_didi', age:120});
for (i=0; i<my_array.length; i++)
{
alert(my_array[i].name);
}
How about
function Struct(name, value) {
this.name = name;
this.value = value;
}
arr[0] = new Struct("name1", "value1");
Javascript objects are loose objects: properties can be added and removed dynamically. So making a new Struct(), as you suggest, does -not- guarantee that the returned object will always have the properties you expect it to have. You have to check the availability of properties at the point of usage (duck typing):
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (Object.hasOwnProperty.call(element, "name")
&& Object.hasOwnProperty.call(element, "value")) {
_tag[element.name] = element.value;
}
}
(Also, I'm just guessing that _tag is an object itself, but that wasn't clear from your example.)
You could probably use a more succinct syntax, but that depends heavily on the values of the properties. For example, you -might- be able to use something like this:
var i, element;
for (i = 0; i < array.length; i++) {
element = array[i];
if (element.name && element.value) {
_tag[element.name] = element.value;
}
}
But you need to realize that the above condition will be false not only if one or both of the properties (name and value) are undefined but also if the value of either or both refers to the empty string, null, 0, NaN, or false.

Categories