I am creating a function which uses an array to navigate through a JSON object, pushing its keys to a results array at each step. The trouble is, I can't get the loop to use the updated object with each successive loop.
JSON object:
myData = {
'Eye': {
'Abnormal Morphology': [
'Neoplasm',
'Abnormality of the globe'
],
'Abnormal Physiology': [
'Hemorrhage',
'Ptosis',
'Ocular pain'
]
},
'Ear': {
'Outer Ear': [
'Abnormality of the pinna',
'Abnormal location of ear',
'Extra chondra fold'
],
'Middle Ear': [
'Glue ear',
'Otitis media'
]
}
}
And the function:
view = ['Ear', 'Outer Ear']
getMenuItems(object, array) {
let menuItems = Object.keys(object);
let result = [menuItems];
for (let item in array) {
object = object[item]; // use updated object each time
menuItems = Object.keys(object);
result.push(menuItems);
}
return result;
}
The result I'm expecting is:
[['Eye', 'Ear'], ['Outer Ear', 'Inner Ear'], ['Abnormality of the pinna', 'Abnormal location of ear', 'Extra chondra fold']]
But all I get is:
['Eye', 'Ear']
for( let item in array )
Iterates over the items key (0,1,2). May use of instead to iterate over props:
for( const item of array )
Then it works
Related
I need to have in array with lat/lon points like that:
/*
var polylinePoints = [
[37.781814, -122.404740],
[37.781719, -122.404637],
[37.781489, -122.404949],
[37.780704, -122.403945],
[37.780012, -122.404827]
];
*/
But I need first to sort it by third parameter which is timestamp?
How to do that? I know how to do that in PHP but not in JS
var polylineTimestamp = [
[37.781814, -122.404740, 1666543938],
[37.781719, -122.404637, 1666543938],
[37.781489, -122.404949, 1666543938],
[37.780704, -122.403945, 1666543938],
[37.780012, -122.404827, 1666543938]
];
Then I need to delete (trim) sorted array (delete timestamp) to have something like polylinePoints.
Here is Jsfiddle:
https://jsfiddle.net/qsdaLz7h/
Array .sort() and .map() will get you there. You could combine them, but it'll be easier for you to follow the logic when they're separated, as below.
// I changed your original timestamps to give some difference
var polylineTimestamp = [
[37.781814, -122.404740, 1666543958],
[37.781719, -122.404637, 1666543948],
[37.781489, -122.404949, 1666543968],
[37.780704, -122.403945, 1666543938],
[37.780012, -122.404827, 1666543998]
];
// sort polylineTimestamp by third parameter (timestamp) older first
var sortedarray = polylineTimestamp.sort((a,b)=> {
return a[2] - b[2];
});
// Remove timestamp from resulting array
var polylinePoints = sortedarray.map(el => {
return [el[0],el[1]];
});
// Log to console
console.log(polylinePoints)
u can make a temp var
let arr = []
polylineTimestamp.forEach((el) => {
arr.push([el[0],el[1]])
})
console.log(arr)
//! expected output would be
arr = [
[ 37.781814, -122.40474 ],
[ 37.781719, -122.404637 ],
[ 37.781489, -122.404949 ],
[ 37.780704, -122.403945 ],
[ 37.780012, -122.404827 ]
]
you also can get a new arr the it can filter to not get the index 2 from the origin arr
Here is your answerer:
const TIMESTAMP_POSITION = 2
var polylineTimestamp = [
[37.781814, -122.404740, 1666540000],
[37.781719, -122.404637, 1666541000],
[37.781489, -122.404949, 1666542000],
[37.780704, -122.403945, 1666543000],
[37.780012, -122.404827, 1666544000]
];
polylineTimestamp.sort(function (a, b) {
// Turn your timestamp number into dates, and then subtract them
// to get a value that is either negative, positive, or zero.
return new Date(b[TIMESTAMP_POSITION]) - new Date(a[TIMESTAMP_POSITION]);
})
//map to remove timestamp
var polyLineArray = polylineTimestamp.map(function (polyLine) {
return [polyLine[0], polyLine[1]]
})
I used the sort function to sort your initial array using date conversion from timestamp.
when just mapping the array to remove the timestamp
I have used csvtojson in order to write the csv data into a sql database, the object that the funcion return to have this structure:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
How can I acces to each field? I am trying to do console.log(prueba[0]["Capacidad"]) in order to see if it is running but it prints "undefined".
'Aula;Capacidad' is seen as a key, so you only can do the following:
console.log(prueba[0]["Aula;Capacidad])
which will write
A10+11;112
to the console.
Your properties are actually named 'Aula;Capacidad', meaning you'd need to use prueba[0]['Aula;Capacidad'] to get the value you are looking for.
This is what you need to iterate through the list of items:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for (var i = 0; i < prueba.length; i++) {
console.log(prueba[i]);
}
If you need to go deeper and iterate over every item properties:
var prueba = [{'Aula;Capacidad': 'A10+11;112'},{'Aula;Capacidad': 'A12;66' }];
for(var i = 0; i < prueba.length; i++) {
for(var p in prueba[0]) {
console.log(p, prueba[i][p]);
}
}
Your key you are looking up is in a composite key. So you would need to look it up with that composite key and than split it.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
console.log(prueba[0]['Aula;Capacidad'].split(";")[1]);
Other choice is to parse it all and look it up by the key.
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
const parsed = prueba.reduce(function (arr, row) {
const entry = Object.entries(row)[0];
const keys = entry[0].split(";");
const values = entry[1].split(";");
const data = keys.reduce(function (o, key, index) {
o[key] = values[index];
return o;
}, {});
arr.push(data);
return arr;
}, []);
console.log(parsed[0].Capacidad);
console.log(parsed[1].Capacidad);
Your data looks malformed so you might need to do some manual processing.
You have an array of two items, both with a single key-value in them. You can do console.log(prueba[0]["Aula;Capacidad"]) and this will return 'A10+11;112'.
You might need to split things by the ; there so you could do something like this:
var prueba = [
{'Aula;Capacidad': 'A10+11;112'},
{'Aula;Capacidad': 'A12;66' }
];
prueba.forEach(item => {
const splitItem = item["Aula;Capacidad"].split(";");
console.log("Each item now looks like this: " + splitItem)
// You can access the first and second part of the item like this
console.log(splitItem[0], splitItem[1])
})
To be honest, I'd go back and look at how this data is being added to your DB. It looks messed up.
I have an object
const Obj = {
2016-07-04: 264464,
2016-07-05: 266458,
2016-07-07: 272720,
2016-07-08: 274352,
2016-07-11: 290110,
2016-07-12: 283604,
2016-07-14: 290356,
2016-07-19: 298452,
2016-07-22: 301793,
2016-07-24: 308439,
2016-07-25: 311762,
2016-07-27: 315518,
2016-07-28: 317712,
2016-07-29: 322961,
2016-07-30: 312415,
2016-07-31: 322962,
2016-08-02: 328265,
2016-08-06: 322963,
2016-08-08: 341632,
2016-08-15: 354271,
2016-08-16: 358108,
2016-08-26: 380486,
2016-08-27: 380495,
2016-08-28: 385578,
2016-08-29: 388026,
2016-08-30: 391542,
2016-09-03: 385575,
2016-09-04: 417260,
2016-09-05: 413816,
2016-09-06: 417249,
2016-09-07: 417244,
2016-09-08: 420326,
2016-09-17: 403546,
}
and I have an array
const daysToCheck = [
"2016-09-01",
"2016-09-02",
"2016-09-03",
"2016-09-04",
"2016-09-05",
"2016-09-06",
"2016-09-07",
"2016-09-08",
];
I want to find out if each of the items in the array exists in the keys of the object and how many of the items of the array are found in the keys of the object.
You can find the intersection of two arrays using .filter method. Easier way of doing than what was proposed above.
let arr = Object.keys(Obj).filter( value => daysToCheck.includes(value));
Object.keys(Obj) extracts the keys of the Obj object, and the .filter return an array with values that are both in daysToCheck and Obj.
Use reduce function on array and for each iteration, check if Obj has the value for the current array element. If it has then increment the accumulator value by one.
const Obj = {
"2016-07-04": 264464,
"2016-07-05": 266458,
"2016-07-07": 272720,
"2016-07-08": 274352,
"2016-07-11": 290110,
"2016-07-12": 283604,
"2016-07-14": 290356,
"2016-07-19": 298452,
"2016-07-22": 301793,
"2016-07-24": 308439,
"2016-07-25": 311762,
"2016-07-27": 315518,
"2016-07-28": 317712,
"2016-07-29": 322961,
"2016-07-30": 312415,
"2016-07-31": 322962,
"2016-08-02": 328265,
"2016-08-06": 322963,
"2016-08-08": 341632,
"2016-08-15": 354271,
"2016-08-16": 358108,
"2016-08-26": 380486,
"2016-08-27": 380495,
"2016-08-28": 385578,
"2016-08-29": 388026,
"2016-08-30": 391542,
"2016-09-03": 385575,
"2016-09-04": 417260,
"2016-09-05": 413816,
"2016-09-06": 417249,
"2016-09-07": 417244,
"2016-09-08": 420326,
"2016-09-17": 403546,
}
const daysToCheck = [
"2016-09-01",
"2016-09-02",
"2016-09-03",
"2016-09-04",
"2016-09-05",
"2016-09-06",
"2016-09-07",
"2016-09-08",
];
const keysInArray = daysToCheck.reduce((acc, cur) => {
if (Obj[cur]) {
acc++;
}
return acc;
}, 0);
console.log(keysInArray);
I want to find strings that has data from the strings from the array 2 in the array1 and save result as separate uniq array.
As can you see I search for not exact values. From the array1 values I know only part of the information, and I want to find the complete strings, with that information, in array1. And at the end I want to save what I found. So, I don't have a problem with finding here, but a problem with saving in the valid single JSON.
Array examples:
Array #1:
{
"overflow": [
"id:address:name:location:email",
...
"id2:address2:name2:location2:email2"
]
}
Array #2:
[
"location:email",
...
"location2:email2"
]
Code:
resultArr: function() {
var arr1 = '/var/log/1.json';
var arr2 = '/var/log/2.json';
var arrResult = '/var/log/result.json';
var arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
for (var i = 0; i < arr2Obj.length; i++) {
var arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return e.includes(arr2Obj[i])
});
fs.appendFile(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
}
My result:
[{
"overflow": [
"id:address:name:location:email"
]
}{
"overflow": [
"id54:address54:name54:location54:email56"
]
}{
"overflow": [
"id2:address2:name2:location2:email2",
"id6:address6:name6:location2:email2"
]
}
What I really want:
{
"overflow": [
"id:address:name:location:email",
"id54:address54:name54:location54:email56",
"id6:address6:name6:location2:email2",
"id2:address2:name2:location2:email2"
]
}
Instead of reading the file again and again, and appending to the result repeatedly, just do both actions only once. All the rest should happen in memory.
You will also get better results (no risk for duplicates in result) when you swap the loops: put the filter action as the outer loop. For the inner loop you can use some, since one match is enough for the entry to be included:
resultArr: function() {
var arr1 = '/var/log/1.json',
arr2 = '/var/log/2.json',
arrResult = '/var/log/result.json',
arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8')),
arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8'));
arr1Obj.overflow = arr1Obj.overflow.filter(function(e) {
return arr2Obj.some(function (f) {
return e.includes(f)
});
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8');
}
At each iteration, you're creating a new object and appening it to a file.
JSON is not a good format to append to.
You're replacing the array instead of adding fields to it.
You can do it that way, it should work :
resultArr: () => {
let arr1 = '/var/log/1.json';
let arr2 = '/var/log/2.json';
let arrResult = '/var/log/result.json';
let arr2Obj = JSON.parse(fs.readFileSync(arr2, 'utf-8'));
let arr1Obj = JSON.parse(fs.readFileSync(arr1, 'utf-8')); // reading only one time
arr1Obj.overflow = arr2Obj.map(value => {
return arr1Obj.overflow.filter(e => return e.includes(value))
});
fs.writeFileSync(arrResult, JSON.stringify(arr1Obj, null, 2), 'utf-8'); //Writing only one time
}
Array.map() executes the closure for each field in your array and group all the values returned by the closure in another array.
I also replaced some keywords to make your code more ES6 compliant. I you really want to append, you should use CSV and not JSON.
I want to create a for loop that will generate a new element for sampleItems based on a fixed number set in a for loop.
var list = new WinJS.Binding.List();
var groupedItems = list.createGrouped(
function groupKeySelector(item) { return item.group.key; },
function groupDataSelector(item) { return item.group; }
);
generateSampleData().forEach(function (item) {
list.push(item);
});
function generateSampleData() {
var sampleGroups = [
{ key: "group1", title: "Event1", backgroundImage: "/images/event1.jpg"}
];
var sampleItems = [
{ group: sampleGroups[0], title: "Item Title: 1", content: "http://192.168.201.41/Stream" + [i] + ".mp4", backgroundImage: "/images/image1.jpg" }
];
return sampleItems;
}
I tried to place a for loop within sampleItems but i'm not allowed place the loop there.
As per conversation in question comments, here is the basic array population code for js:
var streams = 7;
var sampleItems = [];
for(i = 0; i < streams; i++) {
sampleItems.push({'a': 'b', 'c': 'd'})
}
Replace {'a': 'b', 'c': 'd'} with desired key-value pairs
Well you are looping over an array containing one object as entry. what you probably want to do is to discard you object structure completely and just use an simple array like:
var sampleItems = [ sampleGroups[0], "Item Title: 1", ..... ];
you could also make it a an actual object without using arrays but it seems to me that you want to use the List. If no List ist necessary just put the whole object genereated by
generateSampleData into you object or append it to an existing object.