I have an array of objects (pre_finalTab_new below) like this:
My goal is to group them by "schema", and then by "tip" and insert into new array, something like this:
var celotnaTabela = {};
for (var nov in pre_finalTab_new)
{
var shema = pre_finalTab_new[nov].schema.trim();
var objekt_tip = pre_finalTab_new[nov].type.trim();
var objekt_name = pre_finalTab_new[nov].name.trim();
var tip = pre_finalTab_new[nov].tip.trim();
if (celotnaTabela[shema] === undefined)
{
celotnaTabela[shema] = [];
if (celotnaTabela[shema][tip] === undefined)
{
celotnaTabela[shema][tip] = [];
if (celotnaTabela[shema][tip][objekt_tip] === undefined)
{
celotnaTabela[shema][tip][objekt_tip] = [];
celotnaTabela[shema][tip][objekt_tip] = [objekt_name];
} else
celotnaTabela[shema][tip][objekt_tip].push(objekt_name);
}
} else
{
if (celotnaTabela[shema][tip] === undefined)
{
celotnaTabela[shema][tip] = [];
}
if (celotnaTabela[shema][tip][objekt_tip] === undefined)
{
celotnaTabela[shema][tip][objekt_tip] = [];
celotnaTabela[shema][tip][objekt_tip] = [objekt_name];
} else
{
if (!celotnaTabela[shema][tip][objekt_tip].includes(objekt_name))
celotnaTabela[shema][tip][objekt_tip].push(objekt_name);
}
}
}
Then if i output celotnaTabela, i got this:
Expanded:
Even more:
But the problem is, when i try to use JSON.stringify(celotnaTabela), i got this:
{"HR":[],"ZOKI":[]}
But i need it to be in a right format, so i can pass this object into AJAX call..
Can anyone help me with this, what am i doing wrong?
i hope i understood everything right you asked for.
Next time provide the testdata and the wished result in textform pls.
var obj = [
{ schema: "HR", type: " PACKAGE", name: "PAKET1", tip: "new_objects" },
{ schema: "HR", type: " PACKAGE", name: "PAKET2", tip: "new_objects" },
{ schema: "HR", type: " PROCEDURE", name: "ADD_JOB_HISTORY", tip: "new_objects" },
{ schema: "ZOKI", type: " TABLE", name: "TABELA2", tip: "new_objects" },
{ schema: "ZOKI", type: " TABLE", name: "TABELA3", tip: "new_objects" },
];
var out = {};
for (var i = 0, v; v = obj[i]; i++) {
var a = v.schema.trim();
var b = v.type.trim();
var c = v.tip.trim();
var d = v.name.trim();
if (!out.hasOwnProperty(a)) {
out[a] = {};
}
if (!out[a].hasOwnProperty(b)) {
out[a][b] = {};
}
if (!out[a][b].hasOwnProperty(c)) {
out[a][b][c] = []
}
out[a][b][c].push(d);
}
console.log(JSON.stringify(out, null, 2));
I want to sum total depending for each department without duplicates.
Yesterday user #yBrodsky helped me with that and suggested to use SQL but today I want to add a couple options and I can't do this in sql.
Main problem:
I have an array like:
var data = [{
dept:"test",
task_time:"83"
},{
dept:"test",
task_time:"41"
},{
dept:"other",
task_time:"10"
}];
And I want to sum task_time for every dept: for example test = 124 and other = 10.
There is a function which should calculate it but it works like test = 83. test = 41 and other = 10. And shows every dept instead one with sum.
There is function.
var totalPerDept = {};
angular.forEach(data, function(item) {
if(!totalPerDept[item.dept]) {
totalPerDept[item.dept] = 0;
}
totalPerDept[item.dept] += parseFloat(item.task_time);
});
Here's the above as a snippet:
var data = [{
dept:"test",
task_time:"83"
},{
dept:"test",
task_time:"41"
},{
dept:"other",
task_time:"10"
}];
var totalPerDept = {};
angular.forEach(data, function(item) {
if(!totalPerDept[item.dept]) {
totalPerDept[item.dept] = 0;
}
totalPerDept[item.dept] += parseFloat(item.task_time);
});
console.log(totalPerDept);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
I did some modifications to your code to obtain an array with the result you want:
function sumDeptData() {
var data = [{
dept:"test",
task_time:"83"
},{
dept:"test",
task_time:"41"
},{
dept:"other",
task_time:"10"
}];
var totalPerDept = [];
angular.forEach(data, function(item) {
var index = findWithAttr(totalPerDept, 'dept', item.dept);
if (index < 0) {
totalPerDept.push({
dept: item.dept,
total: parseFloat(item.task_time)
});
} else {
totalPerDept[index].total += parseFloat(item.task_time);
}
});
return totalPerDept;
}
function findWithAttr(array, attr, value) {
for(var i = 0; i < array.length; i += 1) {
if(array[i][attr] === value) {
return i;
}
}
return -1;
}
sumDeptData() returns [{"dept":"test","total":124},{"dept":"other","total":10}]
Here is an example using Plain JavaScript.
var data = [{
dept: "test",
task_time: "83"
}, {
dept: "test",
task_time: "41"
}, {
dept: "other",
task_time: "10"
}],
minArr = [];
data.forEach(function(v) {
if (!this[v.dept]) {
this[v.dept] = {
dept: v.dept,
task_time: 0
};
minArr.push(this[v.dept]);
}
this[v.dept].task_time = parseInt(this[v.dept].task_time) + parseInt(v.task_time);
}, {});
console.log(minArr);
I have to merge 2 arrays with key value as follows:
array1 = [
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]},
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]},
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]}]
with
array2 = [
{id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]},
{id:"789", data:[{id:"456",data:"appended data"}]},
{id:"890", data:[{id:"456",data:"new data"}]}]
to produce something like
merged = [
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]},
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"changed"},{id:"yz", data:"data"}]},
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"},{id:"456",data:"appended data"}]},
{id:"890", data:[{id:"456",data:"new data"}]}]
I've been trying this out for quite some time and can't get a solution that meets the scenario. Most of the solutions just do blind merging, not based on the id value. Tried using lodash mergeWith but didn't get the output needed. A Ramda solution is also acceptable.
Thanks,
This links could be helpful to you merge two arrays.
In this code snippet, i have tried to find the common objects between set1 and set2,if there are any i'm finding the unique properties and changing their content and also non existant properties in object2 and pushing it to object1
Check the following snippet.
var arr1 = [{
id: "123",
data: [{
id: "234",
data: "hello"
}, {
id: "345",
data: "there"
}, {
id: "xyz",
data: "yo"
}]
}, {
id: "456",
data: [{
id: "34",
data: "test"
}, {
id: "45",
data: "test2"
}, {
id: "yz",
data: "test3"
}]
}, {
id: "789",
data: [{
id: "23",
data: "aaa"
}, {
id: "34",
data: "bbb"
}, {
id: "xy",
data: "ccc"
}]
}]
var arr2 = [{
id: "456",
data: [{
id: "45",
data: "changed"
}, {
id: "yz",
data: "data"
}]
}, {
id: "789",
data: [{
id: "456",
data: "appended data"
}]
}, {
id: "890",
data: [{
id: "456",
data: "new data"
}]
}]
var arr3 = [];
for (var i in arr1) {
var shared = false;
for (var j in arr2)
if (arr2[j].id == arr1[i].id) {
shared = true;
// arr1[i].data.concat(arr2[j].data);
var set1 = pushproperties(arr1[i].data, arr2[j].data);
arr1[i].data = set1;
arr3.push(arr1[i]);
break;
}
if (!shared) {
arr3.push(arr1[i]);
arr3.push(arr2[j]);
}
}
function pushproperties(set1, set2) {
var filtered = false;
set2.forEach(function(item) {
filtered = set1.every(function(element) {
return element.id != item.id;
});
if (filtered) {
set1.push(item);
}
});
set1.forEach(function(item) {
set2.forEach(function(element) {
if (item.id == element.id) {
item.data = element.data;
}
});
});
return set1;
}
console.log(arr3);
Hope this helps
This a function the merges 2 arrays recursively using Array.prototype.reduce(). If it encounters items with the same id, and they have a data prop, which is an array, it merges them using the logic. If data is not an array, it's overridden by the last item instead.
function mergeArraysDeep(arr1, arr2) {
var unique = arr1.concat(arr2).reduce(function(hash, item) {
var current = hash[item.id];
if(!current) {
hash[item.id] = item;
} else if (Array.isArray(current.data)) {
current.data = mergeArraysDeep(current.data, item.data);
} else {
current.data = item.data;
}
return hash;
}, {});
return Object.keys(unique).map(function(key) {
return unique[key];
});
}
var array1 = [
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]},
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]},
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]}
];
var array2 = [
{id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]},
{id:"789", data:[{id:"456",data:"appended data"}]},
{id:"890", data:[{id:"456",data:"new data"}]}
];
var result = mergeArraysDeep(array1, array2)
console.log(result);
ES6 version that uses Map, Map.prototype.values(), and array spread:
const mergeArraysDeep = (arr1, arr2) => {
return [...arr1.concat(arr2).reduce((hash, item) => {
const current = hash.get(item.id);
if(!current) {
hash.set(item.id, item);
} else if (Array.isArray(current.data)) {
current.data = mergeArraysDeep(current.data, item.data);
} else {
current.data = item.data;
}
return hash;
}, new Map()).values()];
}
const array1 = [
{id:"123", data:[{id:"234",data:"hello"},{id:"345",data:"there"},{id:"xyz", data:"yo"}]},
{id:"456", data:[{id:"34",data:"test"},{id:"45",data:"test2"},{id:"yz", data:"test3"}]},
{id:"789", data:[{id:"23",data:"aaa"},{id:"34",data:"bbb"},{id:"xy", data:"ccc"}]}
];
const array2 = [
{id:"456", data:[{id:"45",data:"changed"},{id:"yz", data:"data"}]},
{id:"789", data:[{id:"456",data:"appended data"}]},
{id:"890", data:[{id:"456",data:"new data"}]}
];
const result = mergeArraysDeep(array1, array2)
console.log(result);
Finally this is what worked for me. Thanks to #Geeky for showing the way:
function mergeArrays(arr1, arr2) {
var arr3, arrIdx = [];
if (!arr1 || arr1.length ==0) return arr2
for (var i in arr1) {
var shared = false;
for (var j in arr2)
if (arr2[j].id == arr1[i].id) {
shared = true;
joined = _.mergeWith({},arr1[i],arr2[j], function (a,b) {
if (_.isArray(a)) return b.concat(a)})
arr3.push(joined);
break;
}
if (!shared) {
arr3.push(arr1[i]);
}
}
for (var k in arr2) {
if (arrIdx[k] !=k) arr3.push(arr2[k])
}
return arr3
}
I have a service that i am using to apply a unique number to a model name. the result i am getting is this
"sectionInputs": [
{
"model": "price_min1"
},
{
"model": "price_max2"
},
{
"model": "units_occ3"
},
{
"model": "inv_mod4"
},
{
"model": "inv_fin5"
},
{
"model": "inv_vdl6"
},
{
"model": "inv_uc7"
},
{
"model": "inv_fut8"
},
{
"model": "inv_con9"
},
{
"model": "units_total10"
}
]
i need this to each have '1'. and then in the next object array i need them to have '2', etc... as of now every object array looks like this. i have a plunker with everything setup.
plunker
function sectionInputSvc(sectionInputs) {
var vm = this;
vm.sectionInputsArry = sectionInputs;
vm.sectionInputs = function () {
var arry = [];
var counter = 0;
for (var i = 0; i < vm.sectionInputsArry.length; i++) {
counter++
var obj = {
model: vm.sectionInputsArry[i].model + counter
};
arry.push(obj);
};
return arry;
};
};
[EDIT 2]
in app.js...
sections[i].sectionInputs = sectionInputSvc.sectionInputs(sections[i],i);
and in section.service.js...
function sectionInputSvc(sectionInputs) {
var vm = this;
vm.sectionInputsArry = sectionInputs;
var obj2={};
vm.sectionInputs = function (obj2,num) {
var arry = [];
var counter = 0;
for (var i = 0; i < vm.sectionInputsArry.length; i++) {
counter++
var obj = {
model: vm.sectionInputsArry[i].model + num
};
arry.push(obj);
};
return arry;
};
};
Using linq.js, and assuming the suffixes do not already exist on the names:
vm.sectionInputs = function () {
return Enumerable.From(vm.sectionInputsArry).Zip(Enumerable.ToInfinity(1),
"{ model: $.model+$$ }"
).ToArray();
};
I have a Javascript Array of objects as follows
var data = [
{
id: 1,
date : '1/1/2011',
todo : 'Maths'
},
{
id: 2,
date : '1/1/2012',
todo : 'Science'
} ................. and soo on
];
I want a resulting data as
var newArray = [
['1/1/2011', '1/1/2012'],
[
{
id:1,
todo: 'Maths'
},
{
id:2,
todo: 'Science'
}
]
]
How can I do that in Javascript efficiently ?
function prepare(data) {
var result = [ [], [] ];
for(var i = 0; i < data.length; i++) {
result[0][i] = data[i].date;
result[1][i] = { id: data[i].id, todo: data[i].todo };
}
return result;
}
var newArray = prepare(data);
try
var data = [{
id: 1,
date: '1/1/2011',
todo: 'Maths'
}, {
id: 2,
date: '1/1/2012',
todo: 'Science'
}];
var array = [];
data.forEach(function (item) {
array.push(item.date);
delete item.date;
})
data.unshift(array)
console.log(data)
I have tried. Its working
var data = [
{
id: 1,
date : '1/1/2011',
todo : 'Maths'
},
{
id: 2,
date : '1/1/2012',
todo : 'Science'
}];
var newArray=formatStr(data);
alert(JSON.stringify(newArray));
function formatStr(data){
arr1=[];
var arr2=[];
for (var i in data) {
var obj={};
obj["id"]=data[i].id;
obj["todo"]=data[i].todo;
arr1.push(data[i].date);
arr2.push(obj);
}
var result=[arr1,arr2];
return (result);
}
If you can use jQuery, then this will work:
var newArray = [[], data];
$.each(data, function(i,v) {newArray[0].push(v.date);delete v.date;});
For pure javascript, this will work:
var newArray = [[], data];
for (var i=0; i<=data.length; i++) {
typeof data[i]==="object" ? (newArray[0].push(data[i].date), delete data[i].date) : '';
}