aggregate in nested ng-repeat - javascript

I want to create a sum of taskAssembly.labour of each taskAssembly object and put it in the totalLabour field
see this plunker. http://plnkr.co/edit/rKnup0IIPRYvh8JLHXbD?p=preview
see my data:
{ "client": "client1","takeoff": [{
"taskName": "ToW",
"taskQnt": 2300,
"totalLabour":"",
"taskAssembly": [
{
"taskName": "ToW",
"taskQnt": 2300,
"taskLabour": 22,
"taskAssembly": [
{ "qnt": 2300, "product": "non-INT", "labour": 12, "application": "spray" },
{ "qnt": 2300, "product": "non-INT", "labour": 10, "application": "strips" }
]
},
{
"taskName": "Pens",
"taskQnt": 43,
"taskLabour": 23,
"taskAssembly": [
{ "qnt": 43, "product": "non-INT", "labour": 23, "application": "spray" }
]
}
]}
my code is not exactly doing what I need.
$scope.getTotalLabour = function(){
var total = 0;
for(var i = 0; i < $scope.estimate.takeoff.length; i++){
var item = $scope.estimate.takeoff[i];
total += (item.taskLabour);
}
return $scope.estimate.totalLabour = total;
}
any idea of how I can do this?

Check working demo: JSFiddle
Simply create a nested loop like:
for(var i = 0; i < $scope.estimate.takeoff.length; i++){
var total = 0;
var item = $scope.estimate.takeoff[i];
console.log(item);
for (var j = 0; j < item.taskAssembly.length; j++) {
total += (item.taskAssembly[j].labour);
}
item.totalLabour = total;
}

Related

Group array of objects by key and compare grouped result with date array

How to group array of objects to array with key indexname and compare with dates array
var data= [
{
"indexname": "red",
"data": [
{
"date": "2018-09-07",
"count": 3
}
]
},
{
"indexname": "red",
"data": [
{
"date": "2018-09-05",
"count": 2
}
]
},
{
"indexname": "red",
"data": [
{
"date": "2018-09-06",
"count": 10
}
]
},
{
"indexname": "yellow",
"data": [
{
"date": "2018-09-07",
"count": 6
}
]
}
]
var dates=['2018-08-09','2018-08-07','2018-09-07','2018-09-01','2018-09-06','2018-09-05','2018-09-04','2018-09-03','2018-09-02']
var grouped = _.mapValues(_.groupBy(data.results, 'indexname'),
clist => clist.map(index => _.omit(index, 'indexname')));
required format
var result=[['date','red','yellow'],[2018-08-09,0,0],[2018-08-07,0,0],[2018-09-07,3,6],[2018-09-06,10,0],[2018-09-05,5,0],[2018-09-04,0,0],[2018-09-03,0,0],[2018-09-02,0,0],]
I have an array of object and dates array i want to get the following result
How to acheive this?
Here is the pure javascript representation for the output result you want. Might be improved for 1 or 2 less loops:
var data = [{
"indexname": "red",
"data": [{
"date": "2018-09-07",
"count": 3
}]
},
{
"indexname": "red",
"data": [{
"date": "2018-09-05",
"count": 2
}]
},
{
"indexname": "red",
"data": [{
"date": "2018-09-06",
"count": 10
}]
},
{
"indexname": "yellow",
"data": [{
"date": "2018-09-07",
"count": 6
}]
}
];
var dates = ['2018-08-09', '2018-08-07', '2018-09-07', '2018-09-01', '2018-09-06', '2018-09-05', '2018-09-04', '2018-09-03', '2018-09-02'];
//Prepair index1 of final array an push to see how many colors are present
var index1 = ['date'];
var colors_sorted_arr = [];
var dates_sorted_arr = [];
//Push data to index1 for colors
for (var i = 0; i < data.length; i++) {
if (index1.indexOf(data[i].indexname) == -1) {
index1.push(data[i].indexname)
}
}
//Seperate out data according to color wise
for (var i = 0; i < data.length; i++) {
for (var j = 1; j < index1.length; j++) {
if (data[i].indexname == index1[j]) {
if (colors_sorted_arr[(j - 1)] == undefined) {
colors_sorted_arr[(j - 1)] = [];
colors_sorted_arr[(j - 1)].push(data[i].data[0]);
} else {
colors_sorted_arr[(j - 1)].push(data[i].data[0]);
}
}
}
}
//Now push index1 data to final array
dates_sorted_arr[0] = index1;
//For other data to final array loop through dates array , then inside that loop through all colors
//and then for all colors loop inside each value to check for particular data
for (var i = 0; i < dates.length; i++) {
dates_sorted_arr[(i + 1)] = [];
dates_sorted_arr[(i + 1)].push(dates[i]);
for (var j = 0; j < colors_sorted_arr.length; j++) {
for (var k = 0; k < colors_sorted_arr[j].length; k++) {
if (colors_sorted_arr[j][k].date == dates[i]) {
dates_sorted_arr[(i + 1)].push(colors_sorted_arr[j][k].count);
}
}
}
for (var l = 0; l < index1.length; l++) {
if (dates_sorted_arr[(i + 1)].length != index1.length) {
dates_sorted_arr[(i + 1)].push(0);
}
}
}
//After creating above got final result what you want
console.log(dates_sorted_arr);

javascript looping changing values of other objects

for (var i = 0; i < itemArray.length; i++) {
//console.log(itemArray[index].mats);
var newMatArray = [];
for (var j = 0; j < itemArray[i].mats.length; j++) {
var mat = itemArray[i].mats[j];
if (isInNewArray(mat.id, newMatArray)) {
continue;
}
for (var k = 0; k < itemArray[i].mats.length; k++) {
var mat2 = itemArray[i].mats[k];
if (k == j) {
continue;
}
if (mat.id == mat2.id) {
//if (itemArray[i].id == 12005) console.log("adding " + mat.quantity + " of " + mat.name + " to " + mat2.quantity);
mat.quantity = mat.quantity + mat2.quantity;
}
}
newMatArray.push(mat);
}
//if (itemArray[i].id == 12005) console.log(newMatArray);
itemArray[i].mats = newMatArray;
}
function isInNewArray(id, array) {
for (var i = 0; i < array.length; i++) {
if (array[i].id == id) {
return true;
}
}
return false;
}
So this loop is supposed to iterate over an array of items and remove/combine duplicate mats required for an item, each item is a json object with a name/id and a mats array of objects and each mat has a name/id/quantity required. For some reason if i iterate over only 1 item at some point in the array then continue on all the rest without combining it works totally fine.
It's only when its looping that changing the values of previous objects seems to change the value of future objects resulting in mats hitting quantities of 1.17555e^105 which is way higher than they should be. Does javascript do some kind of memory optimization that might be storing mat objects with identical values to the same location so when i increase the quantity on objects earlier in the loop it does so for objects later in the loop? Otherwise I don't understand why this algorithim works for 1 off objects but looping over objects and only ever changing one object at a time messes it up.
Edit: sample object below
{
"id": 622,
"bpid": 692,
"quantity": 1,
"name": "Stabber",
"mats": [
{
"id": 34,
"name": "Tritanium",
"quantity": 48518335
},
{
"id": 35,
"name": "Pyerite",
"quantity": 11828791
},
{
"id": 36,
"name": "Mexallon",
"quantity": 40000
},
{
"id": 37,
"name": "Isogen",
"quantity": 10333
},
{
"id": 38,
"name": "Nocxium",
"quantity": 2778
},
{
"id": 39,
"name": "Zydrine",
"quantity": 1244
},
{
"id": 40,
"name": "Megacyte",
"quantity": 244
},
{
"id": 20411,
"name": "Datacore - High Energy Physics",
"quantity": 8
},
{
"id": 20172,
"name": "Datacore - Minmatar Starship Engineering",
"quantity": 8
}
]
}
for (var i = 0; i < matsArray.length; i++) {
var item = matsArray[i];
var type = parseInt(item.typeID, 10);
var index = findItemIndex(type);
if (index > -1) {
var mat = {
id: parseInt(item.materialTypeID, 10),
name: itemIDMap.get(parseInt(item.materialTypeID, 10)),
quantity: parseInt(item.quantity, 10)
}
itemArray[index].mats.push(mat);
} else {
if (bpMap.get(parseInt(item.typeID, 10)) == undefined) {
//console.log(item);
continue;
}
var newItem = {
id: bpMap.get(parseInt(item.typeID, 10)).itemID,
bpid: parseInt(item.typeID, 10),
quantity: bpMap.get(parseInt(item.typeID, 10)).quantityPerRun,
name: itemIDMap.get(bpMap.get(parseInt(item.typeID, 10)).itemID),
mats: []
}
var mat = {
id: parseInt(item.materialTypeID, 10),
name: itemIDMap.get(parseInt(item.materialTypeID, 10)),
quantity: parseInt(item.quantity, 10)
}
newItem.mats.push(mat);
itemArray.push(newItem);
productsArray.push(newItem.id);
}
}
Would this array creation code create identical mat objects? Shouldn't each newly created mat be a separate object?

Update array objects with a single array in JavaScript

I'm having difficulty updating object values from a separate array.
Example:
mainArray = [
{ "name": "bob", "complete": "25" },
{ "name": "john", "complete": "50" },
{ "name": "mike", "complete": "75" },
];
colorArray = ["#ff0000", "#00ff00", "#0000ff"];
I need to create a new Array that combines these values.
for (i = 0, ilen = mainArray.length; ilen > i; i++) {
newArray.push({
name: mainArray[i].name,
complete: mainArray[i].complete,
color: '',
});
}
No matter what I do, I either only get #0000ff back or can't get anything working at all. Failed attempt:
for (j = 0, jlen = newArray.length; jlen > j; j++) {
for (k = 0, km = colorArray.length; km > k; k++) {
newArray[j].color = colorArray[k];
}
}
Goal is to get back:
newArray = [
{ "name": "bob", "complete": "25", "color": "#ff0000" },
{ "name": "john", "complete": "50", "color": "#00ff00" },
{ "name": "mike", "complete": "75", "color": "#0000ff" }
];
What is the correct way to do this?
Just set the color key of each person based on the index of the colorArray.
var mainArray = [
{ "name": "bob", "complete": "25" },
{ "name": "john", "complete": "50" },
{ "name": "mike", "complete": "75" },
];
var colorArray = ["#ff0000", "#00ff00", "#0000ff"];
var newArray = [];
for (var i = 0; i < mainArray.length; i++) {
newArray.push({
name: mainArray[i].name,
complete: mainArray[i].complete,
color: colorArray[i]
});
}
A more functional approach using Array.map and Object.assign looks like
var mainArray = [
{ "name": "bob", "complete": "25" },
{ "name": "john", "complete": "50" },
{ "name": "mike", "complete": "75" },
];
var colorArray = ["#ff0000", "#00ff00", "#0000ff"];
var newArray = mainArray.map((x, i) =>
Object.assign({}, x, {color: colorArray[i]})
)
console.log(newArray);
You have an unnecessary nested loop below:
for (j = 0, jlen = newArray.length; jlen > j; j++) {
for (k = 0, km = colorArray.length; km > k; k++) {
newArray[j].color = colorArray[k];
}
}
You may change it to :
for (j = 0, jlen = newArray.length; jlen > j; j++) {
newArray[j].color = colorArray[j];
}

Many to Many mapping objects in javascript

Am having two sets of arrays :
$scope.selectedEmployees = ["1001", "1002"];
$scope.selectedTasks = ["Task1", "Task2"];
I wanted to generate an array of objects by combining the employees and tasks like a many to many relationship.The length of $scope.selectedEmployees and $scope.selectedTasks may vary :
newArray=[
{
"empId": 1001,
"task": "Task1"
},
{
"empId": 1001,
"task": "Task2"
},
{
"empId": 1002,
"task": "Task2"
},
{
"empId": 1002,
"task": "Task2"
}
]
The method I tried:
var newArray=[];
for (var i = 0; i <$scope.selectedEmployees.length; i++) {
for (var j = 0; j <$scope.selectedTasks .length; j++) {
newArray.push({"empId":$scope.selectedEmployees[i],
"task":$scope.selectedIntervention[j]
})
}
}
But i'm not able to get the required format.Any help will be grateful.
http://jsfiddle.net/zuv8y9wk/
Also instead of selectedTasks, selectedIntervention was used
var $scope = {};
$scope.selectedEmployees = ["1001", "1002"];
$scope.selectedTasks = ["Task1", "Task2"];
var newArray = [];
for (var i = 0; i < $scope.selectedEmployees.length; i++) {
for (var j = 0; j < $scope.selectedTasks.length; j++) {
newArray.push({
"empId": $scope.selectedEmployees[i],
"task": $scope.selectedTasks[j]
})
}
}
console.log(newArray)

Javascript: How to get object from object in an array

Sample data:
{
"data": [
{
"name": {
"full": "JOHN",
"rank": "SENIOR"
},
"mobile": "12345"
},
{
"name": {
"full": "HENRY",
"rank": "SENIOR"
},
"mobile": "67890"
},
{
"name": {
"full": "SAM",
"rank": "JUNIOR"
},
"mobile": "54321"
}
]
}
i'm trying to get the total number of senior members from the data sample above, and i can get the data.name and data.mobile, but i can't get the 'rank' data from the parent 'name' object. can anyone please guide me to obtain the rank data. below is my javascript:
function countRank(rank) {
var i;
for (i in rank.data) {
if (rank.data[i] == "SENIOR") {
i++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + i;
}
}
<div id="senior"></div>
Try this JSFIDDLE
function countRank(rank) {
var k=0;
for (var i=0; i< rank.data.length; i++) {
if (rank.data[i].name.rank == "SENIOR") {
k++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + k;
}
}
countRank(rank);
You can make something like this
var rank = {
"data": [{
"name": {
"full": "JOHN",
"rank": "SENIOR"
},
"mobile": "12345"
}, {
"name": {
"full": "HENRY",
"rank": "SENIOR"
},
"mobile": "67890"
}, {
"name": {
"full": "SAM",
"rank": "JUNIOR"
},
"mobile": "54321"
}]
};
function countRank(rank) {
var i = 0,
arr = rank.data;
for (var j = 0; j < arr.length; j++) {
for (var prop in arr[j]) {
if (arr[j][prop].rank == "SENIOR") {
i++;
}
document.getElementById('senior').innerHTML = 'Total senior members: ' + i;
}
}
}
countRank(rank);
myObject.data[0].name.rank
>>> "SENIOR"
Assuming that whole object is called obj:
var i=0;
for (i=0; i < obj.data.length; i++) {
console.log(obj.data[i].name.rank);
}
function countRank(rank) {
var count = 0;
var arr = rank.data;
for (var i=0; i<arr.length; i++) {
var name = arr[i].name;
if (name.rank == "SENIOR") {
count++;
}
}
alert(count);
}
I checked it and it worked well.
Using jQuery you can find rank from above data easily.
checkout sample on jsFiddle
http://jsfiddle.net/uBnfu/
$.each(jsonData.data, function (index, value) {
alert(value.name['rank']);
});

Categories

Resources