Create variables based on array - javascript

I have the following array and a loop fetching the keys (https://jsfiddle.net/ytm04L53/)
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
alert(feed.match(/\d+$/));
}
The array will always contain different number of keys, What I would like to do is either use these keys as variables and assign the value after the : semicolon as its value or just create a new set of variables and assign the values found on these keys to them.
How can I achieve this? so that I can then perform some sort of comparison
if (test_user > 5000) {dosomething}
update
Thanks for the answers, how can I also create a set of variables and assign the array values to them? For instance something like the following.
valCount(feeds.split(","));
function valCount(t) {
if(t[0].match(/test_user_.*/))
var testUser = t[0].match(/\d+$/);
}
Obviously there is the possibility that sometimes there will only be 1 key in the array and some times 2 or 3, so t[0] won't always be test_user_
I need to somehow pass the array to a function and perform some sort of matching, if array key starts with test_user_ then grab the value and assign it to a define variable.
Thanks guys for all your help!

You can't (reasonably) create variables with dynamic names at runtime. (It is technically possible.)
Instead, you can create object properties:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":"); // Splits the string on the :
obj[parts[0]] = parts[1]; // Creates the property
});
Now, obj["test_user_201508_20150826080829.txt"] has the value "12345".
Live Example:
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
var obj = {};
feeds.forEach(function(entry) {
var parts = entry.split(":");
obj[parts[0]] = parts[1];
});
snippet.log(obj["test_user_201508_20150826080829.txt"]);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

You can do it like this, using the split function:
var i;
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
for (i = 0; i < feeds.length; i++) {
var feed = feeds[i];
console.log(feed.split(/[:]/));
}
This outputs:
["test_user_201508_20150826080829.txt", "12345"]
["test_user_list20150826", "666"]
["test_list_Summary20150826.txt", "321"]

Use the split method
var feeds = ["test_user_201508_20150826080829.txt:12345","test_user_list20150826:666","test_list_Summary20150826.txt:321"];
feedMap = {}
for (i = 0; i < feeds.length; i++) {
var temp = feeds[i].split(':');
feedMap[temp[0]] = temp[1];
}
Yields:
{
"test_user_201508_20150826080829.txt":"12345",
"test_user_list20150826":"666",
"test_list_Summary20150826.txt":"321"
}
And can be accessed like:
feedMap["test_user_201508_20150826080829.txt"]
Here is a codepen

it is not very good idea but if you really need to create variables on-the-run here's the code:
for (i = 0; i < feeds.length; i++)
{
var feed = feeds[i];
window[feed.substring(0, feed.indexOf(":"))] = feed.match(/\d+$/);
}
alert(test_user_201508_20150826080829)
Of course you cannot have any variable-name-string containing banned signs (like '.')
Regards,
MichaƂ

Related

Putting an object into an array in JavaScript

I'm currently working with an MVC JS framework and I want to be able to get a list of objects that I can take a random entry out of on a loop. So far I've managed to create a function that finds a random ID and pulls out that object so that part is not a problem. It's what is going into the array of objects:
QuestionsSetup: function(gameType) {
// Setup Resources
var c = this.View.children;
var player1qs = [];
var leftQ = 0;
var rightQ = 0;
var maxQValue = 50;
var minQValue = 1;
// Fill array with questions
for (var i = 0; i < 5; i++) {
// Build a random question with numbers between 1 and 50
// Build Question Text to output to user
// Generate correct answers based on generated question
// Generate unsorted, incorrect answers and add them to an array
//Place Questions into object
questions.qId = i;
questions.leftQ = leftQ;
questions.rightQ = rightQ;
questions.correctAnswer = correctAnswer;
questions.allAnswers = sortedAnswers;
questions.questionText = questionText;
//Add to array of questions
player1qs.push(questions);
}
}
This does add them to an array but when adding a new object it also changes the values of the existing objects in the array so they all come out the same no matter which one I pull out later. The questions object is declared in it's own file in a models folder. Is there any way, at the start of each loop, to tell the application I want new empty questions object as opposed to referencing the existing ones? I know that you can in similar back end languguages so I refuse to beleive that something so simple doesn't exist in JavaScript too?
Declaring a variable for each array item is definitely missing.
QuestionsSetup: function(gameType) {
// Setup Resources
var c = this.View.children;
var player1qs = [];
var leftQ = 0;
var rightQ = 0;
var maxQValue = 50;
var minQValue = 1;
// Fill array with questions
for (var i = 0; i < 5; i++) {
var tempQuestion = {
qId: i,
leftQ: leftQ,
rightQ: rightQ,
correctAnswer: correctAnswer,
allAnswers: sortedAnswers,
questionText: questionText
}
// ...
//Add to array of questions
player1qs.push(tempQuestion);
}
}
Using a separate closure inside a loop also might be a good idea.
do this:
for (var i = 0; i < 5; i++) {
let questions = {};
// the rest....
you need to define the object first.
Maybe you should just initialize the questions object before initializing its properties, so the code should look like this:
//Place Questions into object
questions = {};
questions.qId = i;
questions.leftQ = leftQ;
questions.rightQ = rightQ;
questions.correctAnswer = correctAnswer;
questions.allAnswers = sortedAnswers;
questions.questionText = questionText;
//Add to array of questions
player1qs.push(questions);

Is there a way to loop this?

Is there a way to loop a declaration of a variable? just a loop to help me declare the variables so i dont have to do the monotonous work of change the numbers of the variable
var height1 = document.getElementById('height1').value;
var height2 = document.getElementById('height2').value;
var height3 = document.getElementById('height3').value;
var height4 = document.getElementById('height4').value;
var height5 = document.getElementById('height5').value;
var height6 = document.getElementById('height6').value;
var height7 = document.getElementById('height7').value;
var height8 = document.getElementById('height8').value;
var height9 = document.getElementById('height9').value;
var height10 = document.getElementById('height10').value;
var height11 = document.getElementById('height11').value;
var height12 = document.getElementById('height12').value;
var height13 = document.getElementById('height13').value;
var height14 = document.getElementById('height14').value;
var height15 = document.getElementById('height15').value;
var height16 = document.getElementById('height16').value;
This is not a right way of coding that, Just do like,
var heights = [];
Array.from(document.querySelectorAll("input[id^=height]")).forEach(function(itm){
heights.push(itm.value);
});
And now you can iterate the array heights to manipulate the values as per your requirement.
The logic behind the code is, querySelectorAll("input[id^=height]") will select the input elements that has id starts with the text height. Since the return value of querySelectorAll is a nodelist, we have to convert it as an array before using array functions over it. So we are using Array.from(nodelist). That will yield an array for us. After that we are iterating over the returned array by using forEach and pushing all element's value into the array heights.
This is almost always an indication that you want an array. Something like this:
var heights = [];
for (var i = 1; i <= 16; i++) {
heights.push(document.getElementById('height' + i).value);
}
Then you can reference a value from the array with something like:
heights[1]
Though technically since in JavaScript your window-level variables are indexable properties of the window object, you can essentially do the same thing with variable names themselves:
for (var i = 1; i <= 16; i++) {
window['height' + i] = document.getElementById('height' + i).value;
}
Then you can still use your original variables:
height1
Though in the interest of keeping things outside of window/global scope, maintaining the array seems a bit cleaner (and semantically more sensible).
This seems to be a good use case for an object:
var heights = {};
for (var i = 1; i <= 16; i++) {
heights[i] = document.getElementById('height' + i).value;
}
Maybe its time to introduce function:
Generally speaking, a function is a "subprogram" that can be called by code external (or internal in the case of recursion) to the function. Like the program itself, a function is composed of a sequence of statements called the function body. Values can be passed to a function, and the function will return a value.
function getHeight(id) {
return document.getElementById(id).value;
}
Call with the wanted id and use it like a variable.
getHeight('height1')
Normally you would put them in an array.
var heights = []
for (i = 1; i < 17; i++) {
heights[i] = document.getElementById('height' + i).value;;
}
Beware this will give you a hole at the start of the array ie heights[0] has nothing in it. If you use this to iterate it won't matter...
for (var i in heights) {
alert(heights[i]);
}

Javascript loop push into global array

1.I want to push id[i] into global array.After I pushed then it will be id.length numbers items in each array,but it will be error and says y is not a function.how to solve it?
2.the sendrequest in the bottom will send a xmlhttprequest to server,but I don't understand why it will run first and then the function(parResponse) will be fire after tmpReadRequest.sendReadRequest(); has down.
Thanks a lot
var tes0=new Array();
var tes1=new Array();
var tes2=new Array();
var tes4=new Array();
var tes5=new Array();
function ReadValuePath(id, Variable,id_2) {
var tmpReadCB = function(parResponse)
{
for (var tmpIndex = 0; tmpIndex < parResponse.length; tmpIndex++)
{
var tmpItemValue = parResponse[tmpIndex];//console.log(tmpItemValue);
var tmpValue = (tmpItemValue.mItemValue) ? tmpItemValue.mItemValue : tmpItemValue.mItemResultId;
if(document.getElementById(id[tmpIndex]) != null && document.getElementById(id_2[tmpIndex]).value != 0)
{
document.getElementById(id[tmpIndex]).value = parseFloat(tmpValue).toFixed(2);
}
}
return true;
}
var tmpReadRequest = new OPCReadRequest("DE", tmpReadCB);
for(var z=0;z<5;z++ ){
for(var i = 0; i < id.length; i++)
var y="tes"+z;
y.push(id[i]);
tmpReadRequest.addItem("ab", Variable[i]);
}
}
tmpReadRequest.sendReadRequest();
}
"A variable declared outside a function, becomes GLOBAL.
A global variable has global scope: All scripts and functions on a web page can access it. " # Source
Y is not an array so .push() won't work on it. # Source
To access the global scope through a string literal like you are trying you can use the window object which is the current global scope.
So in your case it would be window[y].push(id[i]);
Another option would be to change you scructure slightly as personally i don't like accessing the window directly.
so you could define your arrays like
var arrays = {
tes0: [],
tes2: [],
tes3: [],
tes4: [],
tes5: [],
}
and access them like:
arrays[y].push(id[i])
EDIT according to comments
So you want to access global variable in a loop. You are half way there. What your doing is building a string y which contains the property name then using that in the square brackets to access that property.
So with the window option that would be:
for(var z=0;z<5;z++ ){
var y="tes"+z;
for(var i = 0; i < id.length; i++)
window[y].push(id[i]);
}
}
or with the second object option
/*
Because arrays is an object we can use Object.keys
This will return an array of the keys in our object which we can loop over to access each one
*/
Object.keys(arrays).forEach(function(key) {
for(var i = 0; i < id.length; i++)
arrays[key].push(id[i]);
}
});
Hope that helps explain

Creating Objects inside objects using a Constructor

In the below code I am trying to create an object named "portfolio" inside which
I want to create other objects that contain the properties "stockvalue" and "price"?
var portfolio_create = function(stock,stockvalue,price)
{
for(i in stock)
{
this[stock[i]] = stock[i];
this[stock[i]]["stockvalue"] =stockvalue[i];
this[stock[i]]["price"]=price[i]
}
}
var portfolio = new portfolio_create(["ibm","tcs"],[23,34],[34,45]);
var stock_market = portfolio;
alert(portfolio["ibm"]["stockvalue"]); // undefined
Why does the alert return "undefined" and not 23?
Thnaks in advance.
var portfolio_create = function (stock, stockvalue, price) {
for (var i = 0, len = stock.length; i < len; i++) {
this[stock[i]] = {};
this[stock[i]]["stockvalue"] = stockvalue[i];
this[stock[i]]["price"] = price[i];
}
}
var portfolio = new portfolio_create(["ibm", "tcs"], [23,34], [34,45]);
Don't use for..in for arrays.
this[stock[i]] = stock[i]; replace to this[stock[i]] = {};.
Example
I think there is a little confusion here, between objects and variables.
You can create a real JavaScript class portfolio, which contain a collection of another class stock, which contain 2 variables value and price.
In your portfolio class, you can add a AddStock methode, and a GetStock.
Look at JavaScript Classes, I think you will find your hapiness.
Steeve
And try to use libs like underscore or lodash to get rid of these for loops (each). It is much nicer and more functional.
A little bit shorter:
this[stock[i]] = { stockvalue: stockvalue[i], price: price[i] };

Javascript - clearing duplicates from an array object

Hi
I have a javascript array object rapresenting the amount of items sold in a given country, like this:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item2', 'c3':110}]
I need to avoid duplicates (as you may see, the last two 'records' have the same Country and the same Item) and sum the amounts; if I was getting data from a database I would use the DISTINCT SUM clause, but what about it in this scenario? Is there any good jquery trick?
You could use an object as a map of distinct values, like this:
var distincts, index, sum, entry, key;
distincts = {};
sum = 0;
for (index = 0; index < data.length; ++index) {
entry = data[index];
key = entry.c1 + "--sep--" + entry.c2;
if (!distincts[key]) {
distincts[key] = true;
sum += entry.c3;
}
}
How that works: JavaScript objects are maps, and since access to properties is an extremely common operation, a decent JavaScript implementation tries to make property access quite fast (by using hashing on property keys, that sort of thing). You can access object properties using a string for their name, by using brackets ([]), so obj.foo and obj["foo"] both refer to the foo property of obj.
And so:
We start with an object with no properties.
As we loop through the array, we create unique key from c1 and c2. It's important that the "--sep--" string be something that cannot appear in c1 or c2. If case isn't significant, you might throw a .toLowerCase in there.
If distincts already has a value for that key, we know we've seen it before and we can ignore it; otherwise, we add a value (true in this case, but it can be just about anything other than false, undefined, 0, or "") as a flag indicating we've seen this unique combination before. And we add c3 to the sum.
But as someone pointed out, your last two entries aren't actually the same; I'm guessing that was just a typo in the question...
jQuery may have an array function for this, but because your two Italy objects are not distinctly unique, your asking for a custom solution. You want to populate a array and check it for duplicates as you go:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item1', 'c3':110}]
var newArray = [];
var dupeCheck = {}; // hash map
for(var i=0; i < data.length; i++){
if(!dupeCheck[data[i].c1]){
newArray.push(data[i]);
dupeCheck[data[i].c1] = true;
}
}
test
HTML:
<div id="test"></div>
JS:
var data = [{'c1':'USA', 'c2':'Item1', 'c3':100},
{'c1':'Canada', 'c2':'Item1', 'c3':120},
{'c1':'Italy', 'c2':'Item2', 'c3':140},
{'c1':'Italy', 'c2':'Item1', 'c3':110}];
var
l = data.length, // length
f = "", // find
ix = "", // index
d = []; // delete
for (var i = 0; i < l; i++) {
ix = data[i].c1 + "_" + data[i].c2 + "__";
//var re = new RegExp(ix);
//if (re.test(f))
if (f.indexOf(ix) != -1)
d.push(i);
else
f += ix;
}
for (var i1 = 0; i1 < d.length; i1++){
$("#test").append("<div>for delete: "+d[i1]+"</div>");
}
EDIT
Although chrome works much faster, works only in chrome faster the example with indexOf, then in IE/Opera/Firefox/Safary works faster with an object.
The code created by "# TJ Crowder" is much more efficient.

Categories

Resources