How to generate an array of dictionaries with a For loop - javascript

The way I'm currently generating my array of dictionaries is very hard-wired in, and I'd rather not do it that way. Top 3 doesn't necessarily have 3 items, I used that name for other reasons. For example, if I know Top 3 will contain two items in addition to the search term, it will look like this:
var top3Titles = [];
var top3Prices = [];
var top3ImgURLS = [];
var top3ItemURLS = [];
//where the title, price, and img url are sent over to the app
matchCenterItems.forEach(function(item) {
var title = item.title[0];
var price = item.sellingStatus[0].convertedCurrentPrice[0].__value__;
var imgURL = item.galleryURL[0];
var itemURL = item.viewItemURL[0];
top3Titles.push(title);
top3Prices.push(price);
top3ImgURLS.push(imgURL);
top3ItemURLS.push(itemURL);
});
// 10 results per MC Item, only showing 4 by default
var top3 =
{
"Top 3":
[
{
"Search Term": searchTerm
},
{
"Title": top3Titles[0],
"Price": top3Prices[0],
"Image URL": top3ImgURLS[0],
"Item URL": top3ItemURLS[0]
},
{
"Title": top3Titles[1],
"Price": top3Prices[1],
"Image URL": top3ImgURLS[1],
"Item URL": top3ItemURLS[1]
},
]
};
return top3;
What I want to do instead is to have the number of dictionaries after the initial Search Term depend on how many item objects there are in the matchCenterItems array. I figured I could do this using a for loop, but I'm not entirely sure how to format it for this purpose. Rather than having separate arrays for titles, prices, etc, I want it to be an object with a title property for example.

You could initialize an array inside top3 and add the objects while iterating over one or your arrays (top3Titles, top3Prices etc).
Like so:
var top3 = {'Top 3': [{'Search Term': searchTerm}]};
for (var i in top3Titles) {
top3['Top 3'].push({
'Title': top3Titles[i],
'Price': top3Prices[i],
'Image URL': top3ImgURLS[i],
'Item URL': top3ItemURLS[i]
});
}
Or, even better, you could replace everything you've posted with:
var top3 = {'Top 3': [{'Search Term': searchTerm}]};
matchCenterItems.forEach(function(item) {
top3['Top 3'].push(
{
'Title': item.title[0],
'Price': item.sellingStatus[0].convertedCurrentPrice[0].__value__,
'Image URL': item.galleryURL[0],
'Item URL': item.viewItemURL[0]
});
});
return top3;
But the point here is, the return belongs inside a function, as I've told you in my comment to your question.

I don't have good practice in JavaScript , but I can give you Demo of How to generate array of dict using for loop
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
var arr=[];
var i;
var text="";
for(i=0;i<10;i++){
<!-- Creating 10 dictionary in array and initialise with some->
<!--value to check->
arr.push({firstName : "John"})
}
<!-- check that dict is working or not->
for(i=0;i<10;i++){
text=text+arr[i].firstName+'<br />'
}
document.getElementById("demo").innerHTML =
text;
</script>
</body>
</html>
you can run and check it ..

Related

Get values from nested array that are dynamically generated

I am working on a chrome plugin that fetches data. But now i have been running into a problem, I have been asked to put together a nested array with all the data I have retrieved but I have no clue on how to pull this off.
What i want to create:
var messagedata [{
time: messageTime,
Date: messageDate,
Text: messageText
{
time: messageTime,
Date: messageDate,
Text: messageText
}
}];
Note that I know how to create the above when I have the variables. That is not the problem. But in this case i do not know how to declare the variables for each message from the array that is generated.
What i need is a nested array for each message that is in the HTML. So the above example displays 2 arrays but it could be 54 for example.
Code i use to generate normal array:
adiv.innerHTML = cleanupDocString;
trs = adiv.querySelectorAll('tr[bgcolor="#FFFFFF"]');
trs.forEach(function(tr) {
var d = [];
tr.querySelectorAll("td")
.forEach(function(td) {
var img = td.querySelector("img"),
src = img && img.attributes.getNamedItem("src").value;
d.push(src || td.textContent);
});
msgs.push(d);
});
The code above puts this out in console (this example has 2 messages inside it, there are also arrays with 54 messages):
0:Array(6)
0:"2017-08-31T00:00:00"
1:"13:22"
2:"MessageType"
3:ā€¯ClientName"
4:"Subject "
5:"messageText"
length:6
proto:Array(0)
1:Array(6)
0:"2017-08-31T00:00:00"
1:"13:21"
2:" MessageType "
3: "ClientName"
4:" Subject "
5:" messageText "
lenth:6
proto:Array(0)
To make the question easier:
I need to know how i can put the data into a variable that i fetch from the array above. I just don't know how to do it so its dynamic.
What i tried:
var messageDate = msgs[0][0];
var messageTime = msgs[0][1];
var messageType = msgs[0][2];
var messageClient = msgs[0][3];
var messageSubject = msgs[0][4];
var messageText = msgs[0][5];
The above code works but only fetches the first message. I need all the messages that are on the page that is provided. I tried using a ID in the first [] but that also didn't give me the desired result.
Thanks for your help and patience in advance.
Output and code has been slightly edited so it hides personal information
i am assuming msgs is arrray of arrays and the order of properties is guaranteed
var mappedArray = msgs.map((msg)=> {
return {
messageDate : msg[0];
messageTime : msg[1];
messageType : msg[2];
messageClient : msg[3];
messageSubject : msg[4];
messageText :msg[5];
}
})
Edit1
you can use arrayconcat
var mergedArray = mappedArray.concat(otherArray);
To transform the multidimensional array to an array of objects with the help of Array.prototype.map and a simple helper dictionary which defines the index => property mapping.
var messages = [
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
],
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
],
[
"2017-08-31T00:00:00",
"13:22",
"MessageType",
"ClientName",
"Subject",
"messageText",
"unwanted value"
]
];
var mappingDef = {
0: 'messageDate',
1: 'messageTime',
2: 'messageType',
3: 'messageClient',
4: 'messageSubject',
5: 'messageText'
};
function transformMessages(messages, mappingDef) {
return messages.map(function(message) {
var obj = {};
for(var index in mappingDef) {
if(mappingDef.hasOwnProperty(index)) {
obj[mappingDef[index]] = message[index];
}
}
return obj;
});
}
console.log(transformMessages(messages, mappingDef));

Javascript - Switching array name in foreach function

trying to make this as simple to understand as possible...
I have a JS function that essentially picks which array (a list) a person has selected and then passes it to another function to then print that array out. The problem is I can't figure out how to use the array name that I have passed take a look:
Arrays:
var allLists =['list1', 'list2'];
var list1 = ['orange', 'pear', 'apple'];
var list2 = ['car', 'plane', 'bike'];
Function to loop through the lists:
function printAllLists() {
lists.forEach(function(entry) {
count++;
document.write("<h2> List Number " + count + "</h2>");
printList(entry);
});
}
Function to output each list contents to a table
function printList(listname) {
document.write("<table>");
document.write("List Name Is: " + listname);
listname.forEach(function(entry) { //HERE IS THE PROBLEM
document.write("<tr><td>");
document.write(entry);
document.write("</td></tr>");
});
document.write("</table>");
}
The problem I have is the line below literally uses "listname" rather than what has been passed as list name which should be either "list1" or "list 2"
listname.forEach(function(entry) {
So it just fails with this error. How can I get it to swap the name of the array instead. Sorry if its not really clear what I'm trying to say I'm not sure how to exactly word this (which is probably why google isn't helping.)
Uncaught TypeError: listname.forEach is not a function
JSFiddle
Link to JSFiddle - https://jsfiddle.net/38x5nw62/
Thanks
Do it like this:
var list1 = ['car', 'plane', 'bike'];
var list2 = ['car', 'plane', 'bike'];
var allLists = [list1, list2];
Working Code here: https://jsfiddle.net/38x5nw62/1/
You where using var allLists = ['list1', 'list2']; wich does only contain strings 'list1' and 'list2', NOT the variables/arrays named smiliarly to the strings.

How to fill an array with a for loop in Javascript?

I want to create a for loop that will generate a new element for sampleItems based on a fixed number set in a for loop.
var list = new WinJS.Binding.List();
var groupedItems = list.createGrouped(
function groupKeySelector(item) { return item.group.key; },
function groupDataSelector(item) { return item.group; }
);
generateSampleData().forEach(function (item) {
list.push(item);
});
function generateSampleData() {
var sampleGroups = [
{ key: "group1", title: "Event1", backgroundImage: "/images/event1.jpg"}
];
var sampleItems = [
{ group: sampleGroups[0], title: "Item Title: 1", content: "http://192.168.201.41/Stream" + [i] + ".mp4", backgroundImage: "/images/image1.jpg" }
];
return sampleItems;
}
I tried to place a for loop within sampleItems but i'm not allowed place the loop there.
As per conversation in question comments, here is the basic array population code for js:
var streams = 7;
var sampleItems = [];
for(i = 0; i < streams; i++) {
sampleItems.push({'a': 'b', 'c': 'd'})
}
Replace {'a': 'b', 'c': 'd'} with desired key-value pairs
Well you are looping over an array containing one object as entry. what you probably want to do is to discard you object structure completely and just use an simple array like:
var sampleItems = [ sampleGroups[0], "Item Title: 1", ..... ];
you could also make it a an actual object without using arrays but it seems to me that you want to use the List. If no List ist necessary just put the whole object genereated by
generateSampleData into you object or append it to an existing object.

Getting corresponding values from two different objects

I have returned an object from an ajax call that is the combination of two different arrays' of objects. One is Jobs and the second is the corresponding Customer Records for those jobs. The returned object is formatted like so..
{ "jobs" : [
{jobID: 1,
jobLocation: here
},
{jobID: 2,
jobLocation: there
}
],
"customers" : [
{customerID:1,
customerName:Tom
},
{customerID:2,
customerName:Sally
}
]
}
The items in the job array are sequentially related to the customers in the customer array. (i.e. the first customer owns the first job) How can I iterate or parse then iterate over this object to make list objects<li>'s that have are composed of a field from the jobs array and a field from the corresponding object of the customers array? thank you
A plain, old for-loop might do the job:
var customers = obj.customers;
var jobs = obj.jobs;
var $ul = $("<ul></ul>");
for (var i = 0; i < customers.length; i++) {
var customer = customers[i];
var job = jobs[i];
var $li = $("<li></li>").text(customer.customerName + " - " + job.jobLocation);
$li.appendTo($ul);
}
$("#result").append($ul);
See http://jsfiddle.net/XpQms/

Backbone / Underscore Filter multi-dimensional collection

I am currently working on a Backbone app and am using backbone-forms to generate some of the forms used within the app. I have a form with two select boxes that pull data in from collectons via my API.
The second of these select boxes is dependent on the value of the first (category to product relation). However a product can belong to multiple categories so the standard _.where in underscore wont do.
This is what the JSON roughly looks like for a category:
{id: 1, name: "Category 1"}
And then this is the JSON for product:
{id: 1, name: "Product 1", categories: [{cat_id: 1},{cat_id: 2}]}
I need some way to filter on the id when the first select value is chosen.
var categoryId = 1; //your selected category id
var filteredProducts = _.filter(products, function (product) {
return !!_.findWhere(product.categories, {id: categoryId });
});
Worst case efficiency - O(n^2)
fiddle
You could polish your data a little bit so that it's easier to drill down:
_.each(products, function(product) {
product.categoryIds = _.pluck(product.categories, "cat_id");
});
Now you can simply search through it for a certain cat_id with:
var result = _.filter(products, function(product) {
return _.contains(product.categoryIds, cat_id);
});
Or if you want to use a more memory but faster access (useful when multiple selects are made):
var cats = _.reduce(categories, function(map, category) {
map[category.id] = category;
category.products = [];
return map;
}, {});
_.each(products, function(product) {
_.each(product.categories, function(category) {
cats[category.cat_id].products.push(product);
});
});
and then
var result = cats[cat_id].products;

Categories