Related
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)
I have an angular application with Firebase. I want to change the value of an firebase item. Everytime the total KM changes it needs to be set to the right value. so this is my services:
countKm(){
this.totalKmRef = this.db.list(this.uid + '/rides');
this.totalKm$ = this.totalKmRef.valueChanges();
this.totalKm$.subscribe(res=> this.getAllRides(res));
}
getAllRides(res){
this.rides = res;
this.rides.forEach(ride =>{
this.uniqueRides.push(ride.km);
})
this.totalKm = this.uniqueRides.reduce(this.sum);
localStorage.setItem("totalKm", this.totalKm);
}
sum(a, b){
return a += b;
}
Now for some reason, when i add a ride everything is fine, but the second time everything goes wrong.
for example the first time the foreach runs i get (after firebase has already 5 items):
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
}
After i run the foreach 1 time my object list is like this:
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
5: 5,
}
After add a new value the second time and further the foreach does this:
0{
0: 5,
1: 5,
2: 5,
3: 5,
4: 5,
5: 5,
6: 5,
7: 5,
8: 5,
9: 5,
10: 5,
11: 5,
12: 5,
}
Is there some one who can help me? I think it's a wrong configuration in the foreach but can't find out where.
Thanks for you help!
this.uniqueRides.push(ride.km); is just pushing additional items into the array.
Either check to see if the ride is included .includes
this.rides.forEach(ride => {
if(!this.uniqueRides.includes(ride)) {
this.uniqueRides.push(ride.km);
}
})
or clear the array out every time. this.uniqueRides = []
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);
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.
So, I'm a javascript n00b. Have heard that case/switch statements are...passé. I'm trying to wrap my head around object literals as their replacement structure.
After searching and trying various iterations in my code, I still cannot figure out why the "switch" variable value is coming back as "undefined". In my limited experience, a variable with a value of "undefined" usually means that it has no value, right? Is it a variable scope issue?
From what I gather the code is doing is creating a object (mod). The mod object has properties with the name of [3-18]. Each of these properties have values which are functions. These functions return a string value.
Here's what I've got so far:
function getModValue(str) {
var search = str;
var mod = {
3: function() {return "-3";},
4: function() {return "-2";},
5: function() {return "-2";},
6: function() {return "-1";},
7: function() {return "-1";},
8: function() {return "-1";},
9: function() {return "0";},
10: function() {return "0";},
11: function() {return "0";},
12: function() {return "0";},
13: function() {return "+1";},
14: function() {return "+1";},
15: function() {return "+1";},
16: function() {return "+2";},
17: function() {return "+2";},
18: function() {return "+3";}
}
mod[search]();
}
alert(getModValue("14"));
Here is my (non)working example: jsfiddle
Thanks in advance for your help.
The error is just you forgot the return at the end.
I think you are overengineering. This works and it's much more simple:
function getModValue(str) {
var mod = {
3: "-3",
5: "-2",
4: "-2",
6: "-1",
7: "-1",
8: "-1",
9: "0",
10: "0",
11: "0",
12: "0",
13: "+1",
14: "+1",
15: "+1",
16: "+2",
17: "+2",
18: "+3"
}
return mod[str];
}
alert(getModValue("14"));
PS: Checking a 3d6 roll?
UPDATE: Think that mod is a map, where the keys are numbers and the values are strings. When you look for a value using the key, Javascript has to compare your key with the existing ones. Check the following:
var number="1";
number==1 //true, because it's like if '==' makes a "toString()"
number===1 //false
var myObj={hello: function(){ return "Hello";}};
myObj.hello();
myObj["hello"](); // equivalent
const responseToParse = {
3: '-3',
4: '-2',
5: '-2',
6: '-1',
7: '-1',
8: '-1',
9: '0',
10: '0',
11: '0',
12: '0',
13: '+1',
14: '+1',
15: '+1',
16: '+2',
17: '+2',
18: '+3',
19: undefined,
20: null
}
const MyObjectLiteralLibrary = {
3: response => response[3],
4: response => response[4],
5: response => response[5],
6: response => response[6],
7: response => response[7],
8: response => response[8],
9: response => response[9],
10: response => response[10],
11: response => response[11],
12: response => response[12],
13: response => response[13],
14: response => response[14],
15: response => response[15],
16: response => response[16],
17: response => response[17],
18: response => response[18],
19: response => response[19],
20: response => response[20]
}
let str
str = 14
console.log(MyObjectLiteralLibrary[str](responseToParse))
str = 19
console.log(MyObjectLiteralLibrary[str](responseToParse))
str = 20
console.log(MyObjectLiteralLibrary[str](responseToParse))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Nice one; Yes, object literals are better than a switch when some of the cases returning an undefined or a specific cases only. This can be done through switch but will leave a fall-through in many cases.
I played around and came up with this logic in ES6 format. Please look into the code snippet above if that helps.
You can loop over defaultList of cases or a set of required cases. Also, If you want to parse a JSON object this is very helpful.
You have missed return on last line of your api.
return modsearch;