Initially I was working with a CSV, where each row contained data e.g.
------------------------------------------------------
123 | cat | dog |
------------------------------------------------------
456 | cat | rabbit |
------------------------------------------------------
789 | snake | dog |
------------------------------------------------------
I am now getting more data with different structure, so I can no longer use a csv. Instead I am using JSON file. The JSON file looks something like this
[
[
{
"ID": 123,
"animal_one": "cat",
"animal_two": "dog"
},
{
"ID": 456,
"animal_one": "cat",
"animal_two": "rabbit"
},
{
"ID": 789,
"animal_one": "snake",
"animal_two": "dog"
}
],
[
2222
],
[
12345
],
[
"2012-01-02"
],
[
"2012-12-20"
]
]
So you can see the additional data. For this part of the application, I only want to work with the first part of the JSON, the part containing animals. The function I have basically works on values only, so I need to make this JSON like the original CSV file, whereby I only have the values, no keys.
So I am loading the JSON file, which is then contained within the variable data
I am then trying something like this
var key = "CUST_ID";
delete data[0][key];
console.log(JSON.stringify(data[0]))
Although this doesnt even work, I think it is the wrong approach anyway. I dont want to define the keys I want removed, I just want it to remove all keys, and keep the values.
How would I go about doing this? I am using data[0] to get the first section of the JSON, the part that contains animals. Not sure if this is correct either?
Thanks
You can simply do this, if you dont care what keys you are getting:
var collection = "";
data[0].forEach(function(row) {
var line = [];
Object.keys(row).forEach(function(key) {
line.push(row[key])
});
collection = collection + line.join(',') + '\n';
})
You will get csv string out of collection
I dont want to define the keys I want removed
You still will need to define which keys you want the values from. One could just take all the values from the object, in arbitrary order, but that's not robust against changes to the data format. Use something like
const table = data[0].map(value => [value.ID, value.animal_one, value.animal_two]);
data[0].forEach(function(row,index) {
data[0][index] = Object.values(data[0][index]);
});
Related
I use basic array to make reference to icons like this:
{name: "text", avatar: srcs[15]}
This works great, but now I dynamically create an array from my json api and it gives me array of objects like this:
{name: "text", avatar: "srcs[15]"}
so I cannot reference to my avatars now. How can I remove double quotes to get my array work again?
Please note that I don't want to get the srcs[15] value to the array, just make a reference to the source array.
The JSON data format does not support references. What you want it not possible.
You need to either:
Put the data you want there explicitly (this may involve duplication) or
Describe the relationship in a way that the program consuming the JSON can interpret as a reference. You could use the reviver argument of JSON.parse to inflate the description back to the data you want to point it to.
JSON is self-contained static data, and it can't reference named variables or objects outside of its own structure.
You can do it like this instead:
{ "name": "text", "avatarIndex": 15 }
And then do one of these to use it:
var avatar = srcs[data.avatarIndex]; // Avatar object in separate variable
// or
data.avatar = srcs[data.avatarIndex]; // Avatar object added into data
You should just put either the value or the whole array , you have also to read about what format json support here
Here's my suggested solutions
var array = [1, 2, 3, 4, 5, 6]
var json1 = {
name: 'test',
value: array
}
console.log("solution 1 :" + json1.value[2])
var json2 = {
name: 'test',
value: array[2]
}
console.log("solution 2 :" + json2.value)
I have a service producing objects that are like triples. They will be in this format:
{ country, attribute, value }
Example:
{ country: 'usa', attribute: 'population', value: 100 }
{ country: 'mexico', attribute: 'population', value: 200 }
{ country: 'usa', attribute: 'areaInSqM', value: 3000 }
Ultimately I want to display these as a table. Rows are countries, columns are attributes. So the table would look like:
| country | population | areaInSqM |
| usa | 100 | 3000 |
| mexico | 200 | |
My assumption (possibly wrong) is that I need to create an intermediate data structure that is an array of rows. Such as:
[ { country: 'usa', population: 100, areaInSqM: 3000 }, .... ]
My current solution is a non-RxJS mess of objects where I store a Set containing each attribute type, store a lookup object indexed by country, and convert the lookup object back to the above array at the end. Lots of looping and double storage that I'd prefer to avoid.
Does RxJS have any operators that aid in this type of operation?
Is there a smarter approach?
In this particular case, assumptions are:
The attributes are not known ahead of time
The values are always numeric
A given 'cell' can be null. In this example, mexico areaInSqM is never provided
Edit: Plunkr with solution: https://plnkr.co/edit/FVoeVmmzMN7JGJ3zWFQM?p=preview
There are two components in your question, the data structure part, and the data flow part (I suppose you get these data as a stream i.e. one by one, hence the reason why you use Rxjs).
A simple way to iteratively build you data structure is to use the scan operator. For instance :
myDataStructure$ = dataSource$.scan(function (accDataStructure, triple){
accDataStructure[triple.country] = accDataStructure[triple.country] || {}
accDataStructure[triple.country][triple.attribute] = accDataStructure[triple.country][triple.attribute] || {}
accDataStructure[triple.country][triple.attribute] = triple.value
return accDataStructure
}, {})
That makes the assumption that dataSource$ produces objects of the shape { country, attribute, value }. Then myDataStructure$ will output, for every incoming data, the iteratively built data structure that you are seeking. If you only want that data structure once it is finished building, just add a .last() to myDataStructure$.
This is not tested so let me know if that worked
I use Papa Parse 4. When I use Papa.unparse(collection) it seems to create the columns of the resulting table from the first document in my JSON collection. I want all possible fields of my collection be represented in the resulting table.
An example:
{ "name": "Ross" },
{ "name": "Bob", "age": 63 }
creates a table with only one column: "name":
name
Ross
Bob
I want:
name age
Ross
Bob 33
How do I make Papa Parse use the "biggest" of my JSON objects to create the columns?
Papa parse only takes into account the first JSON for generating the headers. Check this issue for more info. However, you can include the fields from all the JSON objects in your final CSV export by using:
Papa.unparse({
data: [ ... ], // JSON array
fields: [ ... ] // Fields to include in CSV eg. ['name', 'age']
});
I am trying to take a JSON list that is formatted as such: (real list has over 2500 entries).
[
['fb.com', 'http://facebook.com/']
['ggle.com', 'http://google.com/']
]
The JSON list represents: ['request url', 'destination url']. It is for a redirect audit tool built on node.js.
The goal is to put those JSON value pairs in a javascript object with a key value array pair as such:
var importedUrls = {
requestUrl : [
'fb.com',
'ggle.com'
],
destinationUrl : [
'https://www.facebook.com/',
'http://www.google.com/'
]
}
Due to the sheer amount of redirects, I do prefer a nonblocking solution if possible.
You first need to create your object:
var importedUrls = {
requestUrl: [],
destinationUrl: []
}
Now, let's say you have your data in an array called importedData for lack of a better name. You can then iterate that array and push each value to its proper new array:
importedData.forEach(function(urls){
importedUrls.requestUrl.push(urls[0]);
importedUrls.destinationUrl.push(urls[1]);
});
This will format your object as you want it to be formatted, I hope.
I will propose it to you that you take another approach.
Why not have an array of importedUrls, each one with its correspondent keys?
You could have something like:
importedUrls = [
{
requestUrl: 'req',
destinationUrl: 'dest'
},
{
requestUrl: 'req2',
destinationUrl: 'dest2'
},
]
I'm sure you can figure out how to tweak the code I showed to fit this format if you want to. What you gain with this is a very clear separation of your urls and it makes the iterations a lot more intuitive.
I receive an object from MongoDB request.
Below is a snippet of it:
{
"Kost": "Kost1",
"Name": "Name1",
"inventar": [
{
"data": "A",
"name": "thefirst",
"ean": "802.0165.813",
},
{
"ean": "802.6725.277",
"name": "thesecond",
"data": "B",
},
{
"ean": "570.6761.483",
"name": "thethird",
"data": "C",
},
{
"ean": "570.6764.519",
"name": "thefourth",
"data": "D",
}
]
}
Later, I will create a table in Jade with this code:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
each val in obj
td= val
The problem is, that the objects in the Array "inventar" are not sorted. The table has a wrong structure. The current output of the table looks like:
|ean | name | data
--------------------------------------------
|802.0165.813| thefirst | A
|B | thesecond | 802.6725.277
|C | thethird | 570.6761.483
|D | thefourth | 570.6764.519
The first column must be the ean, second the name and third the data. Only the first row is correct. I think its luck.
Its possible to sort the objects in the Array ("inventar") before iterating over it, to get the right structure?
I read somewhere that it is not possible to sort directly in mongoose.
thanks in advance
It appears you are asking about the property order in the object. In ES5 and earlier, properties have NO deterministic order by specification. There are some implementations that will maintain the order the properties were created in, but that was not guaranteed.
In ES6, the spec has been changed to say that properties will remain in the order they are created. But, there is no mechanism for reordering properties on an existing object. If you want to change the order, the work-around would be to create a new object, copy the properties over in the desired order and then replace the original object with the new one.
All that said, normal coding should not care what order the properties are in. You refer to a property on an object as in x.inventar[0].data and it should not matter whether data is the first or last property when you dump the object contents.
Given what you are showing in your sample table, it appears that some piece of code is grabbing the first property and putting it in the first column. That is the wrong way to build the table. Instead, it should grab a specific property name and then the order of the properties on the object simply will not matter. So, I think what you need to do is to fix your jade definition to refer to specific property names, not to just take them in order.
I don't know Jade very well myself, but I think you can do something like this:
table(border='1', cellspacing='3', cellpadding='4')
tr
th(align='center') ean
th(align='center') name
th(align='center') data
each obj in inventar
tr
//edited syntax
td= obj.ean
td= obj.name
td= obj.data