Assigning two dynamic keys to an array - javascript

I've been trying to do this for an hour now and I can't figure it out.
I have this:
data = [
{
"_id": {
"cid": "gbrzjauzju",
"source": "iwowrzlocc"
},
"revenue": 0,
"leads": 484,
"count": 25400
},
{
"_id": {
"cid": "lewyhgnnhz",
"source": "iwowrzlocc"
},
"revenue": 0,
"leads": 166,
"count": 9821
},
]
I am passing in filters as variable filters with ['cid', 'source'] so I can access it as filters[0] filters[1]
What I am trying to do this is:
arr = {}
for item in data
arrdata =
revenue: item.revenue
leads: item.leads
clicks: item.count
arr['results'][item._id.filters[0]][item._id.filters[1]] = arrdata
I want to set the value of cid and source as the key names as the key name so it would be like this:
results =
iwowrzlocc =
lewyhgnnhz =
revenue: 0
leads: 166
clicks: 9821
gbrzjauzju =
revenue: 0
leads: 484
clicks: 25400
How exactly would I accomplish this? Thank you in advance!

Have you tried to not use the "dot syntax" in item._id.filters[0]?
If I were you, I'd try to split the last statement:
var arr = {};
var item_results = {};
var item_cid = {};
for (i in data) {
var item = data[i];
var array_data = {
revenue: item.revenue,
leads: item.leads,
count: item.count
};
item_cid[item._id[filters[1]]] = array_data;
item_results[item._id[filters[0]]] = item_cid;
};
arr['results'] = item_results;
Just to make things more readable and easier to identify possible problems in your code. I hope I could help you in some way! :)

Related

Dynamically creating an object with an array inside

I'm trying to dynamically create a JS object which has an array inside such as this one:
//other values omitted for clarity
"items": [
{
"name": "T-Shirt",
"unit_amount": {
"currency_code": "USD",
"value": "90.00"
},
"quantity": "1",
"category": "PHYSICAL_GOODS"
},
{
"name": "Shoes",
"unit_amount": {
"currency_code": "USD",
"value": "45.00"
},
"quantity": "2",
"category": "PHYSICAL_GOODS"
}
],
I am able to create a single value with this code:
var product = {};
product.name = "T-Shirt";
product.quantity = "1";
product.category = "PHYSICAL_GOODS";
var subproduct = {};
subproduct.currency_code = "USD";
subproduct.value = "90.00";
product.unit_amount = subproduct;
var jsonString= JSON.stringify(product);
Which creates:
{
"name": "T-Shirt",
"unit_amount": {
"currency_code": "USD",
"value": "90.00"
},
"quantity": "1",
"category": "PHYSICAL_GOODS"
}
How can I add up the created values inside the array? I have an onclick event for providing the values for any given "item" in the example. For clarity, I do not know beforehand how many "items" the array will have.
To add the object to an array you should use the array method .push().
You could do it in the following way:
// Object which has a property `items`, where we will store product objects
var main = {
items: []
};
// Create the full product object
var product = {
name: "T-Shirt";
quantity: "1";
category: "PHYSICAL_GOODS";
unit_amount: {
currency_code = "USD";
value = "90.00";
}
};
// Push the new object to the `items` array
main.items.push(product);
You are on the right path, just iterate your code and put it in an array :
var productList = [];
for (var i = 0 ; i < 2; i++) {
// your code
var product = {};
product.name = "T-Shirt";
product.quantity = "1";
product.category = "PHYSICAL_GOODS";
var subproduct = {};
subproduct.currency_code = "USD";
subproduct.value = "90.00";
product.unit_amount = subproduct;
productList.push(product);
}
var answer = JSON.stringify(productList);
console.log(answer);

JavaScript: Creating 2 dimensional array of objects based on condition

I'm working on a project that involves two dimensional arrays of objects. I've been working to try to figure out this answer for a while now, and I have some ideas of how to solve it, but I'm a bit stumped.
Let's assume there are animal shelters in City A and that each can hold 50 animals. Animals are coming in from different parts of the state, but the amount of animals from one place can never be more than 50. Here's an example of the animals coming in.
let animal_shelter_capacity =< 50;
let array 1 = [
{ "region": "NE", quantity: 25 },
{ "region": "NW", quantity: 21 },
{ "region": "SE", quantity: 43 },
{ "region": "SW", quantity: 18 },
{ "region": "Central", quantity: 20}
]
In this example, the animals from NE (25) and NW (21) would go to one shelter (46 animals in total), the animals from SE (43) would go to another shelter (43 animals in total), and the animals from SW (18) and Central (20) would go to a third shelter (38 animals in total). The number of animals in one shelter can never be greater than 50.
So, I need to produce an array that looks like this:
let array2 = [
[ { "region": "NE", quantity: 25 }, { "region": "NW", quantity: 21 }],
[ { "region": "SE", quantity: 43 } ],
[ { "region": "SW", quantity: 18 }, { "region": "Central", quantity: 20} ]
]
I'm able to loop through array1 using forEach, but when it comes to adding until a certain value is reached, then creating a new array of arrays, I'm a little stumped on how to proceed to do this.
Here's what I have so far:
let array2 = [] //instantiate array
array1.forEach(function(element, index, array)
{
let sum = 0;
let capacity = 50;
for (let j = 0; j < array1.length; j++)
{
sum += array1[j].quantity;
if (sum >= capacity)
{
//create the new array consisting of the regions, push it into the larger array2
}
}
})
I'm not sure how to continue doing this. I know I need to do the following:
1. find a way to cut off the addition sequence once the quantity reaches 50
2. reset the sequence
3. form the new arrays and push them into a larger array
Can anyone provide any advice on how to proceed?
Try this. Loop through shelters, if it can fit, add it to the current shelter list. If not, save the current shelter roster and start a new one. After the loop, make sure to save the current roster being written
const locations = [{
"region": "NE",
"quantity": 25
},
{
"region": "NW",
"quantity": 21
},
{
"region": "SE",
"quantity": 43
},
{
"region": "SW",
"quantity": 18
},
{
"region": "Central",
"quantity": 20
}
]
const shelterRoster = [];
const capacity = 50;
let count = 0;
for (let location of locations) {
let shelter = shelterRoster[shelterRoster.length - 1];
if (!shelter || count + location.quantity > capacity) {
shelterRoster.push([location]);
count = 0;
} else {
shelter.push(location);
}
count += location.quantity
}
console.log(shelterRoster);
You can approach this with reduce(), using a custom object as the initial accumulator. When the reduce finish, you will need to do an extra line of code for get your final result.
const animal_shelter_capacity = 50;
const array1 = [
{"region": "NE", quantity: 25},
{"region": "NW", quantity: 21},
{"region": "SE", quantity: 43},
{"region": "SW", quantity: 18},
{"region": "Central", quantity: 20}
];
let obj = array1.reduce((res, curr) =>
{
let test = (curr.quantity + res.c >= animal_shelter_capacity);
return {
r: test ? [...res.r, res.a] : res.r,
c: test ? curr.quantity : res.c + curr.quantity,
a: test ? [curr] : [...res.a, curr]
};
},{r:[], c:0, a:[]});
let newArr = [...obj.r, obj.a];
console.log(newArr);
On the previous code, the accumulated object have the next keys:
r: The array of shelters generated progressively.
c: The counter of animals of the current shelter (see next).
a: The current shelter of animals.
When the reduce finish, the last shelter (that on the property a) will not be on the array of shelters. So, we have to put it manually (this is what the extra line does).
The first point I've come up with, is you need to sort input data first. because your given input ( as asked in the question ) is not the only possible way of having data.
You can have some data like:
let array1 = [
{ "region": "NE", quantity: 25 },
{ "region": "NW", quantity: 21 },
{ "region": "Central", quantity: 20 },
{ "region": "SE", quantity: 43 },
{ "region": "SW", quantity: 18 },
]
and in this example, we should have pushed central and SW together, but not sorting the input at first place will result central and SW in different arrays.
So, conclusion. I think this is gonna work:
var make = function( arr ) {
var res = [],
currentArr = [];
arr.forEach( v => {
sum += v.quantity;
if ( sum <= capacity ) {
currentArr.push( v );
} else {
res.push( currentArr );
currentArr = [ v ];
sum = v.quantity;
}
});
res.push( currentArr );
return res;
},
array1 = [
{ "region": "NE", quantity: 25 },
{ "region": "NW", quantity: 21 },
{ "region": "Central", quantity: 20 },
{ "region": "SE", quantity: 43 },
{ "region": "SW", quantity: 18 }
],
sum = 0,
result,
capacity = 50;
array1.sort( ( a, b ) => {
return a.quantity - b.quantity;
});
console.log( array1 );
result = make( array1 );
console.log( result );

Access nested members in JSON

I'm trying to access members in a json, however I am running into some trouble. Here is an example of one of the json objects, stored in var obj:
var fs = require('fs');
var obj = [
{
"_id": "52d7f816f96d7f6f31fbb680",
"regNum": "0361300035313000002",
"sd": "2013-01-01T00:00:00",
"pd": "2013-01-25T09:30:29Z",
"prd": "2012-12-18",
"p": 1395000000,
"pt": [
{
"name": name here",
"price": 1395000000,
"OKDP": {
"code": "5520109",
"name": "name here"
},
"sid": "25484812",
"sum": "1395000000",
"OKEI": {
"code": "796",
"name": "name two"
},
"quantity": "1"
}
],
"b": 0,
"c": 0,
"s": 0
}
];
I'm trying to access the sid and sum values, by doing the following:
var sid = [];
var sum = [];
obj.forEach(block => {
var sidOut = block.pt.sid;
var sumOut = block.pt.sum;
sid.push(sidOut);
sum.push(sumOut);
});
console.log(sid);
console.log(sum);
I tried the solution here, however, when I run these it gives me [ undefined ] errors.
Why am I unable to access this two values?
if you see your pt is an array of an object [{}] so you need to select which element you want to access so
var sidOut = block.pt[0].sid;
var sumOut = block.pt[0].sum;
should get you the right result

Compare two object arrays and combine missing objects

I have 2 object arrays. The 1st is an array of managers. The 2nd is an array of selected managers from the 1st array. The difference is I added a property selected: true. I need to now replace the the managers in the first array with selected managers. I am doing this with an AngularJS service I created. I'm sure there is much simpler solution so I'm open to suggestions. JavaScript, jQuery, lodash, LINQ.js are good.
I have a plunker and I have displayed the result I need. Notice the manager that does not have the selected:true property.
plunker
var app = angular.module("mainModule", []);
var MainController = function($scope, service) {
var eventUsers = [
{
"event_Users_ID":1009,"event_ID":11,"user_ID":"15e640c1-a481-4997-96a7-be2d7b3fcabb"
},{
"event_Users_ID":1010,"event_ID":11,"user_ID":"250a19be-e661-4c04-9a50-c84b0e7349b7"
},{
"event_Users_ID":1011,"event_ID":11,"user_ID":"4cada7f0-b961-422d-8cfe-4e96c1fc11dd"
},{
"event_Users_ID":1013,"event_ID":11,"user_ID":"a3125317-5deb-426d-bbb1-06d3bd4ebaa6"
}];
var managers = [
{
"id": "15e640c1-a481-4997-96a7-be2d7b3fcabb",
"fullName": "Kul Srivastva"
},{
"id": "250a19be-e661-4c04-9a50-c84b0e7349b7",
"fullName": "Todd Brothers"
}, {
"id": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd",
"fullName": "Rudy Sanchez"
}, {
"id": "79823c6d-de52-4464-aa7e-a15949fb25fb",
"fullName": "Mike Piehota",
}, {
"id": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6",
"fullName": "Nick Broadhurst"
}];
$scope.result = service.eventUserMatch(eventUsers, managers);
};
function service() {
var vm = this;
vm.eventUserMatch = function (eventUsers, managers) {
var arry = [];
arry = $.map(eventUsers, function (eventUser) {
var manager = $.grep(managers, function (user) {
return user.id === eventUser.user_ID;
})[0];
eventUser.id = manager.id;
eventUser.fullName = manager.fullName;
eventUser.selected = true;
return eventUser;
});
return arry;
};
}
app.controller("MainController", MainController);
app.service('service', service);
You can use Array#map.
// Get all the event user IDs in an array
var eventUserIds = eventUsers.map(e => e.user_ID);
// Iterate over managers
managers = managers.map(e => {
// If manager is present in the event users, `select` it
if (eventUserIds.indexOf(e.id) !== -1) {
e.selected = true;
}
return e;
});
var eventUsers = [{
"event_Users_ID": 1009,
"event_ID": 11,
"user_ID": "15e640c1-a481-4997-96a7-be2d7b3fcabb"
}, {
"event_Users_ID": 1010,
"event_ID": 11,
"user_ID": "250a19be-e661-4c04-9a50-c84b0e7349b7"
}, {
"event_Users_ID": 1011,
"event_ID": 11,
"user_ID": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd"
}, {
"event_Users_ID": 1013,
"event_ID": 11,
"user_ID": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6"
}];
var managers = [{
"id": "15e640c1-a481-4997-96a7-be2d7b3fcabb",
"fullName": "Kul Srivastva"
}, {
"id": "250a19be-e661-4c04-9a50-c84b0e7349b7",
"fullName": "Todd Brothers"
}, {
"id": "4cada7f0-b961-422d-8cfe-4e96c1fc11dd",
"fullName": "Rudy Sanchez"
}, {
"id": "79823c6d-de52-4464-aa7e-a15949fb25fb",
"fullName": "Mike Piehota",
}, {
"id": "a3125317-5deb-426d-bbb1-06d3bd4ebaa6",
"fullName": "Nick Broadhurst"
}];
var eventUserIds = eventUsers.map(e => e.user_ID);
managers = managers.map(e => {
if (eventUserIds.indexOf(e.id) !== -1) {
e.selected = true;
}
return e;
})
console.log(managers);
document.getElementById('result').innerHTML = JSON.stringify(managers, 0, 4);
<pre id="result"></pre>
would this work? Loop through the new array of managers, find the index using lodash of a matching manager object in the old manager array and replace it in the old manager array with the manager from the new manager array if found?
There's probably a more efficient way to write a solution to this but assuming I'm understanding your problem correctly I believe this should work? Can't test as I'm at work currently.
for(var i=0; i < SelectedManagersArray.length; i++){
var index = _.findIndex(OldManagersArray, {id: SelectedManagersArray[i].id, fullName: selectedManagersArray[i].fullName);
//I believe lodash returns a -1 if a matching index isn't found.
if(index !== -1){SelectedManagersArray[index] = OldManagersArray[i]}
}
Simple implementation:
for(var i = 0; i < eventUsers.length; i++) {
for(var j = 0; j < managers.length; j++) {
if(eventUsers[i].user_ID === managers[j].id) {
managers[j].selected = true;
}
}
}
As you said, I do think there may be an easier way to do this.
I advise you to pick a look to SugarJs which is a JavaScript library that extends native objects with so helpful methods.
In your case the doc on Arrays.
For me, it helps a lot dealing with a lot of native JavaScript Object (JSON).

Is this valid json data?

The url has following json data:
[{ "topic": "cricket",
"value": "Player [ playerid=123, category=b, high=150, total=2300]",
"place": "xyz"},
{ "topic": "cricket",
"value": "Player [ playerid=456, category=c, high=60, total=300]",
"place": "abc"},
{ "topic": "cricket",
"value": "Player [ playerid=789, category=a, high=178, total=5300]",
"place": "bnm"}]
I tried online to check whether this is valid json or not through following link: http://jsonformatter.curiousconcept.com/ it says valid. if it is, how do I access each playerid ?
It is valid JSON, but the data about the player is embedded in a random string. You can do one of two things:
Update the service to send back a different, valid JS value, for example:
"value": {
"type": "Player",
"playerid": 123,
"category": "b",
"high": 150,
"total": 2300
}
Parse the data in the value key yourself:
// Simple regex, not really "parsing"
var playerIdRE = /playerid=(\d+)/i;
var result = playerIdRE.exec(yourData[0].value);
// result[0] is the full match, while result[1] is the ID.
// Or the more complicated version that does full parsing
var format = /\s*(.*?)\s*\[\s*([^\]]+)\s*\]\s*/gi,
keyValuePair = /(\w+)=([^,\]]*),?\s*/gi
function parseComplexDataType(input) {
var result = format.exec(input),
typeName = result[1],
keyValues = result[2],
returnValue = {};
if (!typeName) return returnValue;
returnValue.typeName = typeName;
input.replace(keyValuePair, function(_, key, value) {
returnValue[key] = value;
});
return returnValue;
}
// Usage:
> parseComplexDataType("Player [ playerid=123, category=b, high=150, total=2300]")
Object {typeName: "Player", playerid: "123", category: "b", high: "150", total: "2300"}
For your purposes, it is not valid. Once the JSON is corrected, you simply need to loop through the array and read each value.
var jArray = [{
"topic": "cricket",
"value": {
"type": "Player",
"playerid": 123,
"category": "b",
"high": 150,
"total": 2300
},
"place": "xyz"
}, {
...
}]
To access the JSON data ...
for (var i=0,len=jArray.length; i<len; i++) {
console.log(jArray[i].topic, jArray[i].value.type);
}
Yes, it is. I check it via: http://jsonlint.com/
Extracting "playerid":
Initialise the string to JSONArray.
Iterate over each element in the above array.
Now, from each element extract "value".
Finally, from this string you can get "playerid" by using string methods (see the code below).
Below is the code in Java:
ArrayList<String> player_ids = new ArrayList<String>();
String s = "YOUR STRING";
JSONArray ja = new JSONArray(s);
for(int i =0; i<ja.length(); i++)
{
String value = ja.getJSONObject(i).getString("value");
int start = value.indexOf("=");
int end = value.indexOf(",");
String player_id = value.substring(start+1, end);
player_ids.add(player_id);
}
Hope it helps!!

Categories

Resources