I have encountered a situation in my code where I have three java script variables in which two are arrays and one is a single string variable. The following are their structure:
var selectedUser = $('#Employees_SelectedValue').val(); //It has one one value "12121"
var selectedCountries = $('#Countries_SelectedValue').val(); //It has multiple values ["IND", "USA"]
var selectedSourceSystems = $('#SourceSystems_SelectedValue').val(); //It has multiple values ["SQL", "ORACLE", "MySQL"]
What I have to do is to add these values in a class on the basis of selectedUser such as User is same for all the values but the remaining two are different as:
var userSettings = { userName: selectedUser, userCountry: selectedCountries, userSourceSystem: selectedSourceSystems };
The situation is to add the values from this class into an array in such a way that every userCountry and userSourceSystem will come as a single entity such as:
{ userName: "12121", userCountry: "IND", userSourceSystem: "SQL" },
{ userName: "12121", userCountry: "USA", userSourceSystem: "ORACLE" },
{ userName: "12121", userCountry: "", userSourceSystem: "MySQL" }
I'm trying the approach of nested-for loop to handle this scenario like:
for (var i = 0; i < selectedCountries; i++)
{
for (var j = 0; j < selectedSourceSystems; j++)
{
userSettings.userName = selectedUser;
//Add i and j values
}
}
Please suggest an effective approach other than this.
You may set up a 3×n matrix ( a 2d array) and rotate it by 90 degrees:
var matrix = [[selectedUser],selectedCountries,selectedSourceSystems];
var result =
Array(//set up a new array
matrix.reduce((l,row)=>Math.max(l,row.length),0)//get the longest row length
).fill(0)
.map((_,x)=> matrix.map((row,i) => row[i?x:x%row.length] || ""));
Result
If result should contain objects, then map the 2d array to objects:
var objects = result.map(([a,b,c])=>({userName:a,userCountry:b,userSourceSystem:c}));
result
Small explanation:
row[i?x:x%row.length] || ""
Actually does the following:
If were in the first row ( i=0 ) ("12121")
take whatever value of the array (x%row.length), so basically always "12121"
if not, try to get the value of the current column(x)
if row[x] doesnt exist (||) take an empty string ("")
A more basic approach:
var result = [];
for(var i = 0,max = Math.max(selectedCountries.length,selectedSourceSystems.length);i<max;i++){
result.push({
userName:selectedUser,
userCountry:selectedCountries[i]||"",
userSourceSystem:selectedSourceSystems[i]||""
});
}
result
I believe it would be better to restructure your userSettings object in more natural way:
userSettings: {
name: "userName",
countries: ["USA", "IND"],
userSourceSystems: ["MySQL", "Oracle"]
}
Then you can fill it with settings from your inputs like this
for (item in selectedCountries)
userSettings.countries.push(item)
for (item in selectedCountries)
userSettings.userSourceSystems.push(item)
Related
I'm trying to somewhat combine 3 arrays to create a new one. So the end result is
<li>array1[0]array2[0]array3[0]</li>
I tried a for loop but it ends up with 27 answers and there should only be 2 with the data I have.
// const ingredientsList = () => {
// for (let i = 0; i < recipe.ingredients.length; i++) {
// for (let j = 0; j < recipe.size.length; j++) {
// for (let k = 0; k < recipe.amount.length; k++) {
// console.log(recipe.amount[k], recipe.size[j], recipe.ingredients[i]);
// <li>
// {recipe.amount[k]}
// {recipe.size[j]}
// {recipe.ingredients[i]}
// </li>;
// }
// }
// }
// };
I would greatly appreciate anyone's help. I'm currently working in reactjs. Each array is the same length. I have 3 arrays: ingredient list, amount, and size. So I want to combine them so they read smoothly such as "1 cup flour"
The way you are looping through the three arrays will end up as such (in pseudo code):
Loop through the first array and for every element:
Loop through the second array and for every element:
Loop through the third array and
for every element create a list item of each element at index n from
each array.
Since I am not sure exactly what you are wanting I will have to assume they are the same length arrays so you can do:
for(let i = 0; i < recipe.amount.length; i++) {
console.log(`${recipe.amount[i]} ${recipe.size[i]} ${recipe.ingeredients[i]}`)
}
This should get you logging the appropriate results, then just create the html list elements.
If I understand correctly based on the code in the question, you have three arrays (ingredients, size, amount).
If each of the arrays is the same length and each index's data corresponds to the data at the same index of the others, you could write a loop using the length of one of them and pass the same index into each array like...
for (let i = 0; i < recipe.ingredients.length; i++) {
console.log(
recipe.ingredients[i],
recipe.size[i],
recipe.amount[i],
);
}
Seeing as you're working in react though, if you have control over the data yourself, it would probably make more sense to store each instruction in an object in a recipe array, then map over that array and create the list item like...
Somewhere in the component could be something like...
this.recipe = [
{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
},
{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
},{
ingredient: 'something',
amount: 'some amount',
size: 'some size',
}
]
and in the template...
{
recipe.map((instruction) => (
<li>
{ instruction.amount }
{ instruction.size }
{ instruction.ingredient }
</li>
));
}
const emp1 = ["Cecilie", "Lone"];
const emp2 = ["Emil", "Tobias", "Linus"];
const allEmp = emp1.concat(emp2);
you can try using concat keyword to merge arrays. In case of more than two arrays you can use
emp3 = ["john", "lacy"]
const allEmp = emp1.concat(emp2, emp3);
I have two data structures (they are much longer, these are just excerpts)
var data = [
{count: 6, zip: "78705"},
{count: 4, zip: "78754"},
{count: 33, zip: "78757"}
]
var txcodes = [
{county: "SWISHER", code: "437"},
{county: "TARRANT", code: "439"},
{county: "TAYLOR", code: "441"},
{county: "TRAVIS", code: "453"}
]
I have written code that successfully goes through “data” and takes the zipcode and retrieves the corresponding county (from an external website via HTTP request). It returns a structure that looks like
results = {
TRAVIS: 8,
TAYLOR: 1
}
(8 and 1 are examples of counters for how many times a zipcode from data occurs…basically a running count).
What I need to do next is use the keys from results to look up what the corresponding code in txcodes is. How do I do this?
var currentCounty = str.result[0].County
returns the county from results.
console.log(txcodes[i].county + " " + txcodes[i].code)
prints the county & code from txcodes.
I’m a little confused on how to do this. It seems like a relatively simple concept but I can’t seem to get the desired result. Can someone please point me in the right direction?
If county names are unique and if you are going to be making repeated lookups, you should build a "map" of the codes out of the array:
var txcodesByCounty = txcodes.reduce(function(p, c) {
p[c.county] = c.code;
return p;
}, {});
You can then look up codes directly from this map.
Build a lookup map like this :
var lookupMap = {};
for (var i = 0; i < txcodes.length; i++) {
var element = txcodes[i];
lookupMap[element.county] = element;
}
Then you can simply do this to print the desired output :
console.log(lookupMap[currentCounty].county + " " + lookupMap[currentCounty].code);
If the county in your result is only available as a key, you'll need to for..in, Object.keys or Object.getOwnPropertyNames to access them.
After, access the details via a map as others have suggested
var county, found = [];
for (county in results)
found.push(map[county]);
So what you get back from your HTTP request is a simple object, and you need to access its property names. You can do that easily with Object.keys:
resultKeys = Object.keys(result);
This will give you an array of the object properties:
[ "TRAVIS", "TAYLOR" ]
You can easily iterate over this array now, and inside you ask your result object for its value:
for (var i = 0; i < resultKeys.length; i++) {
console.log(resultkeys[i] + ": " + result[resultkeys[i]]);
}
Using this technique, you can use for example underscore.js libary to easily filter for your desired data:
for (var i = 0; i < resultKeys.length; i++) {
console.log(_.filter(txcodes , function(key){ return txcodes.county== resultkeys[i]; }));
}
I have an object, with nested objects. How do I target a specific index of the object and loop through all the nested values of image. As you will note the length of the nested objects vary.
Target example: productArray[0].image = test1.png, test2.png, test3.png
var products = [
//item1
{
identifier: "item-0",
image: {
"img1": "test1.png",
"img2": "test2.png",
"img3": "test3.png"
}
},
//item2
{
identifier: "item-1",
image: {
"img1": "test1.png",
"img2": "test2.png"
}
},
//item3
{
identifier: "item-2",
image: {
"img1": "test1.png",
"img2": "test2.png",
"img3": "test3.png",
"img4": "test4.png",
"img5": "test5.png",
"img6": "test6.png",
"img7": "test7.png"
}
}
];
We can do this. What you need to do is a simple loop through the object at a specific index, or you can target them all. Note that the image object is not an array, so it will not have an accurate length property.
Target all indexes:
for(var i = 0; i < products.length; i++) {
console.log("Item: " + i);
var images = products[i].image;
for(var a in images)
console.log(images[a]);
}
Target specific:
for(var i in products[0].image)
console.log(products[0].image[i]);
I used a for loop here, but you can use a while loop if you would like.
example
Steps:
You need to iterate over your original array of products. products
Each element (product) will be in format { identifier: "", image : {"img1" : "img2", ..}} products[i]
You get the image property of current product - this is an object. products[i].image
Now you need to iterate over the properties of the image object. products[i].image[j]
Code:
for(var i = 0; i < products.length; i++)
{
for(var j in products[i].image)
{
// Here you have all the images for the current product.
// You can print them, group them or whatever you want to do with them
console.log(products[i].image[j]);
}
}
Also you can change the code (introduce variables) to be more readable.
var strs = (function( obj ) {
var ret = [];
for( im in obj ) {
ret.push( obj[im] );
//You could access each image URL here
//ad strs in the end will have all of them
//comma-separated after this code completes
// im is the key, obj[ im ] the value
}
return ret.join(',');
})( products[0].image );
console.log( strs );
WORKING JS FIDDLE DEMO
Here is another way of doing this, with newer functions in ECMAScript 5
var images = Object.keys(products[2].image).map(function(key){
return products[2].image[key]
})
console.log(images) // Returns: ["test1.png", "test2.png", "test3.png", "test4.png", "test5.png", "test6.png", "test7.png"]
How It Works:
Object#keys returns an array of key names. Array#map creates a new array using the keys from Object#keys. By looking up the key from the object you get the value, which will be the image name.
JS FIDDLE
I need to store (many) objects or arrays of data, which need to have the following criteria:
I need to be able to add a new set of data into the existing data easily
I need to be able to sort the data by date/ time added easily (array in order of when entries were pushed to it)
I need to be able to grab an entry easily using a reference, either integer or string. This is important, at the moment I have to do an $.each() to loop through my data until I find the entry I want.
I have tried using a structure like:
saved_info = {
1001: {//all my data for ref 1001},
1002: {//all my data for ref 1002}
}
which gave me what wanted of being able to grab the info easily given a reference:
info = saved_info[1001];
however, the reference numbers I use aren't in order - I use a reference given to me (its a unique identifier), therefore the object isn't in order of when items were added/saved/pushed.
You can use two objects:
One that stores the data by key
Another that stores the sort order
This way you can (i) lookup an element by key (ii) loop over elements in the order they were inserted. Rough outline of the structure:
var DataObject = {
data: {},
sort: []
};
Here is how you add data to this structure:
DataObject.data[1004] = {name: "Test 4"};
DataObject.sort.push(1004);
DataObject.data[1001] = {name: "Test 1"};
DataObject.sort.push(1001);
DataObject.data[1003] = {name: "Test 3"};
DataObject.sort.push(1003);
DataObject.data[1002] = {name: "Test 2"};
DataObject.sort.push(1002);
Here is how you perform a random access:
console.log(DataObject.data[1001].name);
console.log(DataObject.data[1003].name);
And here is how you iterate over all elements in the order they were added:
var i;
for (i = 0; i < DataObject.sort.length; i++) {
console.log(DataObject.data[DataObject.sort[i]].name);
}
It is possible to wrap the entire logic inside a class:
function DataObject() {
this.data = {};
this.sort = [];
this.setItem = function (k, v) {
this.data[k] = v;
this.sort.push(k);
};
this.getItemByKey = function (k) {
return this.data[k];
};
this.getItemByPos = function (i) {
return this.data[this.sort[i]];
};
this.getAllItems = function () {
var i, r = [];
for (i = 0; i < this.sort.length; i++) {
r.push(this.data[this.sort[i]]);
}
return r;
};
}
var t = new DataObject();
t.setItem(1001, {name: "Test 1"});
t.setItem(1002, {name: "Test 2"});
t.setItem(1003, {name: "Test 3"});
t.setItem(1004, {name: "Test 4"});
console.log(t.getItemByKey(1001));
console.log(t.getItemByPos(0));
console.log(t.getAllItems());
Try to build a Json like this,
var xJson = {
"1001":{//all my data for ref 1001},
"1002":{//all my data for ref 1002}
};
and you can fetch the records as per your wish using the bracket notation, since we are using a numeric value as a key.
var xData = xJson["1001"];
I am trying to build a data structure.
In my limited knowledge, 'hash table' seems to be the way to go. If you think there is an easier way, please suggest it.
I have two, 1-dimensional arrays:-
A[] - contains names of badges (accomplishment)
B[] - contains respective dates those achievements were accomplished from array A[].
An achievement/accomplishment/badge can be accomplished more than one time.
Therefore a sample of the two arrays:-
A['scholar', 'contributor', 'teacher', 'student', 'tumbleweed', 'scholar'.....,'scholar',......]
B['1/2010', '2/2011', '3/2011', '6/2012', '10/2012', '2/2013',......'3/2013',........]
What I want to achieve with my data structure is:-
A list of unique keys (eq:- 'scholar') and all of its existing values (dates in array B[]).
Therefore my final result should be like:-
({'scholar': '1/2010', '2/2013', '3/2013'}), ({'contributor' : ........})..........
This way I can pick out a unique key and then traverse through all its unique values and then use them to plot on x-y grid. (y axis labels being unique badge names, and x axis being dates, sort of a timeline.)
Can anyone guide me how to build such a data structure??
and how do I access the keys from the data structure created.... granted that I don't know how many keys there are and what are their individual values. Assigning of these keys are dynamic, so the number and their names vary.
Your final object structure would look like this:
{
'scholar': [],
'contributor': []
}
To build this, iterate through the names array and build the final result as you go: if the final result contains the key, push the corresponding date on to its value otherwise set a new key to an array containing its corresponding date.
something like:
var resultVal = {};
for(var i = 0; i < names.length; ++i) {
if(resultVal[names[i]]) {
resultVal[names[i]].push(dates[i]);
} else {
resultVal[names[i]] = [dates[i]];
}
}
Accessing the result - iterating through all values:
for(var key in resultVal) {
var dates = resultVal[key];
for(var i = 0; i < dates.length; ++i) {
// you logic here for each date
console.log("resultVal[" + key + "] ==> " + resultVal[key][i]);
}
}
will give results like:
resultVal[scholar] ==> 1/2010
resultVal[scholar] ==> 2/2013
resultVal[scholar] ==> 3/2013
resultVal[contributor] ==> 2/2011
resultVal[teacher] ==> 3/2011
resultVal[student] ==> 6/2012
resultVal[tumbleweed] ==> 10/2012
You can try this...
var A = ['scholar', 'contributor',
'teacher', 'student', 'tumbleweed', 'scholar','scholar'];
var B = ['1/2010', '2/2011',
'3/2011', '6/2012', '10/2012', '2/2013','3/2013'];
var combined = {};
for(var i=0;i<A.length;i++) {
if(combined[A[i]] === undefined) {
combined[A[i]] = [];
}
combined[A[i]].push(B[i]);
}
Then each one of the arrays in combined can be accessed via
combined.scholar[0]
or
combined['scholar'][0]
Note the === when comparing against undefined