Multiply associative array by object where the keys match in JavaScript - javascript

I am trying to figure out the best way to multiply the values from an associative array by the values within an object where the keys match.
I have a JavaScript object with this structure:
Object {0: Object, 1: Object, 2: Object, 3: Object, 4: Object, 5: Object, 6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object, 13: Object, 14: Object, 15: Object, 16: Object, 17: Object, 18: Object, 19: Object, 20: Object}
0: Object
migforeign: 0.236575072366489
migmunicip: 0.0560288755282917
municipality: "Abrantes"
popdent: 0.0297202684601973
ppunit: 0.535590943544069
qagedep: 0.396652635764728
qfemale: 0.318397957136199
qfhh: 0.563231479514655
qforeign: 0.0569742908463333
qrental: 0.60538345279747
qurban: 0.507952069302096
__proto__: Object
1: Object
migforeign: 0.473038759939619
migmunicip: 0.09940842629884
municipality: "Alcanena"
popdent: 0.0653282502099797
ppunit: 0.72859029845259
qagedep: 0.30339392964618
qfemale: 0.306467891932506
qfhh: 0.685415625421922
qforeign: 0.27560826506132
qrental: 0.626947992275036
qurban: 0
__proto__: Object
2: Object ...
I have an associative array:
var assosArray = [migforeign: 8.3, migmunicip: 4, popdent: 3, ppunit: 10, qagedep: 3, qfemale: 2.5, qfhh: 8.3, qforeign: 8.5, qrental: 2, qurban: 2]
I am trying to create a new object like this:
Object {0: Object, 1: Object, 2: Object, 3: Object, 4: Object, 5: Object, 6: Object, 7: Object, 8: Object, 9: Object, 10: Object, 11: Object, 12: Object, 13: Object, 14: Object, 15: Object, 16: Object, 17: Object, 18: Object, 19: Object, 20: Object}
0: Object
migforeign: 1.96357310064186 // 0.236575072366489 * 8.3
migmunicip: 0.22411550211317 // 0.0560288755282917 * 4
municipality: "Abrantes"
popdent: 0.08916080538059 // 0.0297202684601973 * 3
ppunit: 5.35590943544069 // ...
qagedep: 1.18995790729418
qfemale: 0.7959948928405
qfhh: 4.67482127997164
qforeign: 0.48428147219383
qrental: 1.21076690559494
qurban: 1.01590413860419
__proto__: Object
1: Object ...

This may be what you need:
var o = {};
o[0] = { migforeign: 0.236575072366489, migmunicip: 0.0560288755282917 };
o[1] = { migforeign: 0.473038759939619,
migmunicip: 0.09940842629884 }
var assoc = { migforeign: 8.3, migmunicip: 4 };
for(var p1 in o){
for(var p2 in o[p1]){
if(assoc.hasOwnProperty(p2)){
o[p1][p2] *= assoc[p2];
}
}
}
console.log(o);
http://jsfiddle.net/5azF6/

Is that "associative array" of yours even valid syntax? I don't think so - just make it an object (which, in JavaScript, is a dictionary).
Then you could just do something like:
for (var i = 0; values.length; ++i) {
for (var key in assosArray) {
if (assosArray.hasOwnProperty(key)) {
values[i][key] *= assosArray[key];
}
}
}

Your array is not an array. It's an object with properties and values. This will not work:
var assosArray = [migforeign: 8.3, migmunicip: 4, popdent: 3, ppunit: 10, qagedep: 3, qfemale: 2.5, qfhh: 8.3, qforeign: 8.5, qrental: 2, qurban: 2]
This will work:
var assosArray = {
migforeign: 8.3,
migmunicip: 4,
popdent: 3,
ppunit: 10,
qagedep: 3,
qfemale: 2.5,
qfhh: 8.3,
qforeign: 8.5,
qrental: 2,
qurban: 2
};
You can loop your object like this:
var myNewObj = {};
for (prop in obj) {
if ( assosArray[prop] ) {
myNewObj[prop] = assosArray[prop] * obj[prop];
}
}
JSFiddle.
Take a look at your console.

Related

push the total amount of objects to an array

I am trying to count how many times a specific item appears in an array. And then push that amount to an other array. I got the counter working, although when I push this amount to the array the type of this value turn out te be Not A Number...
Here is my code:
res2 =
0: (2) [29682885, "Jean-Paul"]
1: (2) [29682886, "DEMO Martin"]
2: (2) [29682887, "Johan"]
3: (2) [29682892, "Peter"]
4: (2) [29682900, "Antoine"]
5: (2) [29682902, "Sandra"]
6: (2) [29682906, "Kevin"]
7: (2) [29682910, "Wouter"]
8: (2) [29682911, "Tom"]
9: (2) [4, "Autotask"]
res3 =
0: (2) [29682885, "2019-05-16T08:25:32Z"]
1: (2) [29682885, "2019-07-01T13:11:00Z"]
2: (2) [29682885, "2019-07-03T10:21:07Z"]
3: (2) [29682885, "2019-09-03T14:00:45Z"]
4: (2) [29682885, "2019-09-11T09:59:07Z"]
5: (2) [29682885, "2019-09-17T14:13:39Z"]
6: (2) [29682885, "2019-10-09T16:48:41Z"]
7: (2) [29682885, "2019-10-30T13:48:12Z"]
8: (2) [29682885, "2019-10-30T14:13:01Z"]
9: (2) [29682885, "2019-10-30T14:34:13Z"]
10: (2) [29682885, "2019-11-07T13:41:27Z"]
11: (2) [29682885, "2019-11-22T12:41:08Z"]
...
res2.sort();
res3.sort();
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
console.log(person[1]);
} else {
person[1].occurrences++;
console.log(person[1]);
prepArray.push(person[1]);
}
prepArray.push(person[1]);
}
});
});
prepArray.push(person[1]); retruns an NaN somehow. But the console shows the exact amount I would like to push to my prepArray...
I've used a mix of filter, flat, map to achieve this. Added code comments to explain what logic is being used.
res2 = [[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"]]
res3 = [[29682885, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682885, "2019-09-17T14:13:39Z"],
[29682902, "2019-10-09T16:48:41Z"],
[4, "2019-10-30T13:48:12Z"],
[4, "2019-10-30T14:13:01Z"],
[29682911, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]];
// pick only the ids from res3
// this makes it easier for comparison
let res = res3.map(v => {
return v.shift();
}).flat()
let final = [];
// loop over res2, and count occurrences using .filter().length
res2.map(sale => final.push([sale[1], res.filter(person => person === sale[0]).length]));
console.log(final);
// if you want the output as an object,
// you can do the following
let finalObj = {};
res2.map(sale => finalObj[sale[1]] = res.filter(person => person === sale[0]).length);
console.log({ finalObj })
I've modified the input set (res3) slightly to show the difference in counts, the above code outputs the following,
[
[
"Jean-Paul",
5
],
[
"DEMO Martin",
0
],
[
"Johan",
0
],
[
"Peter",
0
],
[
"Antoine",
0
],
[
"Sandra",
2
],
[
"Kevin",
0
],
[
"Wouter",
0
],
[
"Tom",
3
],
[
"Autotask",
2
]
]
Edited my answer to get the desired output in object format, so now you'll get,
{
"Jean-Paul": 5,
"DEMO Martin": 0,
"Johan": 0,
"Peter": 0,
"Antoine": 0,
"Sandra": 2,
"Kevin": 0,
"Wouter": 0,
"Tom": 3,
"Autotask": 2
}
I don't understand many parts of your code, but trying to interpretate it:
res2 = [
[29682885, "Jean-Paul"],
[29682886, "DEMO Martin"],
[29682887, "Johan"],
[29682892, "Peter"],
[29682900, "Antoine"],
[29682902, "Sandra"],
[29682906, "Kevin"],
[29682910, "Wouter"],
[29682911, "Tom"],
[4, "Autotask"],
];
res3 = [
[29682911, "2019-05-16T08:25:32Z"],
[29682885, "2019-07-01T13:11:00Z"],
[29682902, "2019-07-03T10:21:07Z"],
[29682885, "2019-09-03T14:00:45Z"],
[29682885, "2019-09-11T09:59:07Z"],
[29682902, "2019-09-17T14:13:39Z"],
[29682885, "2019-10-09T16:48:41Z"],
[29682885, "2019-10-30T13:48:12Z"],
[29682885, "2019-10-30T14:13:01Z"],
[29682885, "2019-10-30T14:34:13Z"],
[29682911, "2019-11-07T13:41:27Z"],
[29682911, "2019-11-22T12:41:08Z"]
]
res2.sort();
res3.sort();
const prepArray = {};
res3.forEach(sale => {
res2.forEach(person => {
if (sale[0] === person[0]) {
if (person[1] === undefined) {
person[1] = 1;
}
prepArray[person[1]] = prepArray[person[1]] || 0;
prepArray[person[1]] += 1;
}
});
});
console.log(prepArray)

Angular -> Parsing JSON data into Chart.js bar chart

I have a problem. I have a list of data that I output grouped. Now I want to output the values e.g. erzeugenGes to a barchart. Chart modules itself works. Fail only at the grouped data for evaluation.
Enclosed my code and list
1,2,3,4,5,6,7,8,9,10,11,12 are the Month for the ChartLabels
1.
1: [{…}]
2: [{…}]
3: [{…}]
4: [{…}]
5: [{…}]
6: [{…}]
7: [{…}]
8: [{…}]
9: Array(1)
0: {jahr: 2020, monat: 9, erzeugungGes: 901.04, verbrauchGes: 952.22, eigenverbrauch: 515.24, …}
length: 1
__proto__: Array(0)
10: Array(2)
0:
bezogen: 252.18
eigenverbrauch: 201.62
eingespeist: 140.94
erzeugungGes: 342.53
jahr: 2019
monat: 10
verbrauchGes: 453.75
__proto__: Object
1:
bezogen: 232.07
eigenverbrauch: 174.13
eingespeist: 102.37
erzeugungGes: 276.48
jahr: 2020
monat: 10
verbrauchGes: 406.19
__proto__: Object
length: 2
__proto__: Array(0)
11: Array(1)
0: {jahr: 2019, monat: 11, erzeugungGes: 291.87, verbrauchGes: 761.16, eigenverbrauch: 238.38, …}
length: 1
__proto__: Array(0)
12: [{…}]
/// and Data
getData() {
this.ds.getAuswertungJahr().subscribe(res => {
this.daten = res;
this.data = this.daten.reduce((r, a) => { console.log("a", a); console.log('r', r); r[a.monat] = [...r[a.monat] || [], a]; return r; }, {}); console.log("group", this.data);
this.barChartData[0].data = [];
for (let i = 0; i < this.data.lenght; i++) {
this.barChartData[0].data.push(this.data[i]);
}
})
}
Thanks

React array being sorted before the function is being called

I was working on displaying the steps to sorting an array and trying to render out the different steps in react. When I call my bubble sort function, the array is already sorted after I click the button.
Creating my state variable:
const [arr, setArr] = useState(resetArr())
function resetArr() {
return new Array(10).fill().map(() => {
return ({
num: Math.floor(Math.random() * 100),
eval: false
})})
}
Bubble sort function
function bubbleSort() {
const history = [];
const sArr = arr.slice();
let len = sArr.length;
for (let i = len-1; i >= 0; i--) {
for (let j = 1; j<=i; j++) {
if (sArr[j-1].num > sArr[j].num) {
const temp = sArr[j-1].num;
sArr[j-1].num = sArr[j].num;
sArr[j].num = temp;
}
history.push(sArr);
}
}
console.log(history)
}
Button and return
return (
<div>
<div className="arr-container">
{arr.map((item, idx) =>
<div key={idx} className="arr-item">
{item.num}
</div>
)}
</div>
<div>
<button onClick={() => bubbleSort()}>Bubble</button>
</div>
</div>
)
Console log for history
0: Array(10)
0: {num: 0, eval: false}
1: {num: 3, eval: false}
2: {num: 9, eval: false}
3: {num: 18, eval: false}
4: {num: 33, eval: false}
5: {num: 41, eval: false}
6: {num: 53, eval: false}
7: {num: 65, eval: false}
8: {num: 94, eval: false}
9: {num: 99, eval: false}
1: Array(10)
0: {num: 0, eval: false}
1: {num: 3, eval: false}
2: {num: 9, eval: false}
3: {num: 18, eval: false}
4: {num: 33, eval: false}
5: {num: 41, eval: false}
6: {num: 53, eval: false}
7: {num: 65, eval: false}
8: {num: 94, eval: false}
9: {num: 99, eval: false}
Any help is appreciated, I am completely stuck on why it's working like this.
You need to understand object references in JavaScript and programming languages in general.
As an example:
const array = [];
const someObject = {
a: "foo"
};
array.push(someObject);
someObject.a = "bar";
array.push(someObject);
console.log(JSON.stringify(array, null,2));
This doesn't print:
[
{
"a": "foo"
},
{
"a": "bar"
}
]
it prints:
[
{
"a": "bar"
},
{
"a": "bar"
}
]
Because in that first push to the array, you aren't pushing the object as it is at the time, you are pushing a reference to the object.
In this scenario, when you later change the objects a property, (you mutate the object) that value changes in the array.
This kind of confusion is why people like to avoid property reassignment like this, why immutable programming is a thing.
Your code basically has the same problem.
You are pushing the same array to the history array each time it loops, and then you are later mutating that array.
If you change your history.push line to this:
history.push(JSON.parse(JSON.stringify(sArr)));
This solves your problems.
What the parse-stringify does is just clones the array object, ie, it creates a new array object.
I don't know if this will be helpful at all, but I decided I might as well link it: sandbox!
I thought it would be nice to have the rendering portion implemented so it would be easier to see what is happening to the data.

Sort of Array<[string, number]> string as a date

I have a list Array<[string, number]> I want to sort this list By the string as a date ASC
my list is like:
0: (2) ["01/09/2020 23:38", 100]
1: (2) ["01/09/2020 23:48", 89]
2: (2) ["01/09/2020 23:36", 100]
3: (2) ["01/09/2020 23:42", 100]
4: (2) ["01/09/2020 23:52", 78]
5: (2) ["01/09/2020 23:40", 100]
6: (2) ["01/09/2020 23:50", 89]
7: (2) ["01/09/2020 23:46", 100]
8: (2) ["01/09/2020 23:56", 78]
9: (2) ["01/09/2020 23:44", 100]
10: (2) ["01/09/2020 23:54", 78]
Use [].sort((a,b)=>a-b) like below:
var dateData=[["01/09/2020 23:38", 100],["01/09/2020 23:48", 89],["01/09/2020 23:36", 100],["01/09/2020 23:42", 100]];
dateData.sort((a,b)=>new Date([a[0]]) - new Date([b[0]]));
console.log(dateData);

Replace javascript swich statement

I have a switch in javascript that I need to put it different.
How can I write this in a better way to avoid the switch?
var types = {
Int: 2,
Short: 3,
Long: 4,
Double: 5,
Decimal: 6,
String: 1,
Guid: 10,
Variant: 11,
};
switch (data.columnTypeId) {
case types.String:
case types.Guid:
case types.Variant:
self.GetStrings(data);
break;
case types.Int:
case types.Decimal:
case types.Short:
case types.Long:
case types.Double:
self.GetNumbers(data);
break;
default:
}
What about doing the same map, but map a function reference instead?
var columnTypes = {
2: self.GetNumbers,
3: self.GetNumbers,
4: self.GetNumbers,
5: self.GetNumbers,
6: self.GetNumbers,
1: self.GetStrings,
10: self.GetStrings,
11: self.GetStrings,
0: self.GetDefault //Guessing the default value would be 0
};
columnTypes[data.columnTypeId](data);
or with a safe check:
if (columnTypes.indexOf(data.columnTypeId) !== -1) {
columnTypes[data.columnTypeId](data);
} else {
self.GetDefault(data);
}
Or as #dandavis pointed out in a comment:
columnTypes[data.columnTypeId || self.getDefault](data);

Categories

Resources