Unable to properly convert array of complex objects to CSV - javascript

I have an array of complex objects, which may contain arrays of more objects. I want to convert these to a CSV file. Whenever there's a list of objects, the data is parsed as [object Object]. If a person has two emails, for example, I want to print these emails in two lines, and so on for each object. Addresses may be concatenated to one string, for example "France, Paris, someStreet 15".
The code is in this pen.
Here's the data:
var names = [
{
Name: [{First: "Peter", Last:"john"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 33.45,
Adress: [{Country:"UK", city: "London", street:"Oak", strtNumber:16},
{Country:"Italy", city: "MIlan", street:"Zabin", strtNumber:2}]
},
{
Name: [{First: "jack", Last:"Smith"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 30,
Adress: [{Country:"Portugal", city: "Lisbon", street:"crap", strtNumber:144},
{Country:"Greece", city: "Athenes", street:"Hercules", strtNumber:55}]
},
{
Name: [{First: "jon", Last:"snow"}],
WorkPlace: [{Company: "Intel", emails: ["jack#intell.com","admin#intell.com"]}],
Age: 50,
Adress: [{Country:"Middle earth", city: "Winterfell", street:"raven", strtNumber:4345},
{Country:"Narnia", city: "Jacksonvile", street:"Great crap", strNumber:34}]
},
];
Right now this is the output:

The mistake is inside your converArrayOfObjectsToCSV-method, as the result of 'item[key]' is an array (in case of 'Name') and you need to specify further how to handle this array, as it otherwise will only be written out to [object Object].
You will have to access the element with i.e. item[key][index] and the iterate over its properties and print them as you need them.

The [object Object] indicates the data needs further conversion to get the desired output.
Here is an updated CodePen with an example conversion.
The conversion routine provided uses Object.values() to convert all data:
function parseArrayOfObjects(arrayOfObj){
return arrayOfObj.map(item =>
Object.values(item).join(" ")) // convert each array item to it's values
.join(" ") // convert final array to string
.replace(",", " "); // remove any commas to preserve csv format
}
Of course, your needs may dictate other conversions, so adjust as needed.

Related

How to access and sort keys in nested objects in Javascript?

I have a nested object like this
info ={
"id-1":
{
name: Jane,
age: 35,
experience: "7+",
position: manager,
},
"id-2":
{
age: 38,
name: John,
position: manager,
experience: "9+",
},
"id-3":
{
age: 42,
experience: "12+",
position: manager,
name: Max,
}
and I have a string
let myString ="name, age,position, experience"
I need to access keys in objects (name, age, position, experience) and sort them according to this string, so keys in the object would be in the same order as in myString, like this:
"id-1":
{
name: Jane,
age: 35,
position: manager,
experience: "7+",
},
How can I access keys in the nested objects and sort them in order? When I try to use Object.keys(info) it returns id-1, id-2, id-3 not name, age, position, experience. Please help, I can't seem to figure out a way.
First, most of the values of your keys are invalid. For example 7+ isn't a string, number or boolean and words like manager and John will be treated like variables if they don't have quotes around them. So your data needs to be fixed up.
Next, instead of wrapping the objects in an object that only has sequential key names (dashes are illegal syntax in key names unless the key names are quoted by the way), just place all the objects in an Array.
Then, just loop over the objects in the array and manually extract the individual key values you want in the order you want them. There is no need to think about re-sequencing the order that they are stored in.
let info = [
{name: "Jane", age: "35", experience: "7+", position: "manager" },
{age: "38", name: "John", position: "manager", experience: "9+"},
{age: "42", experience: "12+", position: "manager", name: "Max"}
];
let keyNames = ["name", "age", "position", "experience"];
// Loop over the objects in the array
info.forEach(function(obj){
let output = ""; // Will hold the output for one object at a time
// Loop over the key names in the array so we go in the desired order
keyNames.forEach(function(key){
// Build up the string with they key name and the key value
output += key + ": " + obj[key] + " ";
});
console.log(output); // Write out the string for the object
});

nested json data minipulation for ngx datatable in angualr -6 / js

I am trying to create a ngx datatable that creates columns dynamically from nested arrays, which with some research is not possible - so to achieve my desired result, I must flatten my nested arrays with the key / values that i need from each nested object into my parent object.
I need to manipulate my data so that my end result is a flat array and contains a line item for each object in the nested array earnings with 'abbreviation' being the key and 'amount' being the value..
I.e
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo
earnings:[{
abbreviation: "NT HRS"
amount: "45.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
},
{
abbreviation: "OT HRS"
amount: "25.00"
money: false
name: "Normal Time HRS"
time: true
unique: "7d783469-717e-408a-bc3c-93115cb632dd_true"
uuid: "7d783469-717e-408a-bc3c-93115cb632dd"
value: "45.00"
}],
terminated false
}
...
]
I'd like to look like this:
[
{
employee_uuid: 978f37df-7e07-4118-be93-d82507ce5c46,
employee_code: JB00024,
full_name: Thulisile Sandra,
last_name: Bhekiswayo,
NT HRS: '45.00',
OT HRS, '25.00',
terminated:false
}
...
]
I am not sure how to go about this, I've tried reducing and map functions but no success.. I can add the nested arrays to the parent object with Object.assign but that takes the whole object, I need to create a new parameter from that object..
Any help would be hugely appreciated..
You can use es6 destructuring for this, simply expose whatever properties you need and then "recompose" then into the object shape you want.
For example:
return myEmployeeArray.map(employee => {
const {earn } = employee
earn.map(field => field.abbreviation)
myDesiredObject = { fieldA: employee.abbreviation....fieldE:field.abbreviation}
}
This would get you one of your nested fields

Javascript - How to add multiple objects into an empty array

I am trying to add multiple objects- Company Names into listBox Companies. I used $scope.companies.push(newCompany[0].name); to add the company into the list. But only the first object's company gets added because I used newCompany[0].name.
Now, how do I add the second company name into the list without entering newCpmpany[1].name ? Say there are 50 companies, I cannot add all 50 by doing this. Is there a better way to add all the names in one go? like a loop or incrementing the element or something? Looking for some help. Thanks in advance.
var newCompany = [{
name: "Huawei", // -->COMPANY NAME
email: "Drath#yahoo.com",
phone: "123-123-1234",
owner: "Drath",
street: "Gin Blvd",
city: "Austin",
country: "USA",
duns:"123112321",
type: "buyer"
},
{
name: "Asus", // -->COMPANY NAME
email: "Vadar#yahoo.com",
phone: "999-123-8888",
owner: "Vadar",
street: "Vince Blvd",
city: "Dallas",
country: "USA",
duns: "123100000",
type: "supplier"
}];
window.localStorage.setItem("newCompany", JSON.stringify(newCompany));
$scope.companies = [];
var newCompany = JSON.parse(localStorage.getItem("newCompany"));
$scope.companies.push(newCompany[0].name);
You can try with spread
$scope.companies.push(...newCompany.map(item => item.name));
or why do you need exactly push? why don't you just init $scope.companies with exact values
var newCompany = JSON.parse(localStorage.getItem("newCompany"));
$scope.companies = newCompany.map(item => item.name)
If spread is not supported just a regular splice of array can be used
var names = newCompany.map(function(company){return company.name});
$scope.companies.splice(-1, 0, names);

Create a simple rank array using map function (JavaScript)

So essentially I have a JSON that it's in the format as so:
JSON= [
{username: foo, score: 12343},
{username: bar, score: 9432},
{username: foo-bar, score: 402, ...
]
I know that the JSON that I am getting back is already rank from highest to lowest, based on the scores.
How can I make an array that automatically inserts the rank position? For instance, I would like to see an output of :
[1, username: foo, score: 12343],
[2, username: bar, score: 9432],
[3, username: foo-bar, score: 402],...
Javascript got you covered already. An array always has indexes, though it starts at zero. If you want the best, just use
console.log(JSON[0]);
and if you insist on 1 being 1, try this
function getByRank(index) {
return JSON[index - 1];
}
so you will get the best with
console.log(getByRank(1)); // {username: "foo", score: 12343}
I think in your code the json is valid json, see the " around foo...
Your syntax seems off, but assuming that the JSON is:
JSON = [
{username: 'foo', score: 12343},
{username: 'bar', score: 9432},
{username: 'foo-bar', score: 402}
]
Since Arrays are 0 indexed and you have access to the current index in a .map method, you can do something along the following:
JSON = JSON.map(function (record, index) {
record.rank = index + 1;
return record;
})
This should give you the following output:
[
{ rank: 1, username: 'foo', score: 12343 },
{ rank: 2, username: 'bar', score: 9432},
{ rank: 3, username: 'foo-bar', score: 402}
]
Hope this helps.
Strictly from the point of view of your question, you already got the answer. I just want to enumerate some ideas, maybe they will be useful to some of you in the future:
First of all, JSON (JavaScript Object Notation) is an open-standard format that uses human-readable text to serialize objects, arrays, numbers, strings, booleans, and null. Its syntax, as the name states, is derived from JavaScript, but JSON is actually a text, a string.
A JSON string is (almost always) syntactically correct
JavaScript code.
Make sure you don't use the keyword "JSON" as the name of a variable, because JSON is actually an existing object in JavaScript, and it is used to encode to JSON format (stringify) and decode from JSON format (parse).
Just try JSON.stringify({a: 2, b: 3}); and JSON.parse('{"a":2,"b":3}'); in a JavaScript console.

Remove Attribute names from Json string

Hi lets say I have a JSON string which represent a record in a grid containing 3 columns Id, Name, Status. I'm currently writing some JavaScript logic where you can filter the rows of data by typing some text in the text box. The filter will be applied to data in all columns. So if I type "James" Record 1 below will be returned an if I type None Record 1 and 2 will be returned. The problem is if I type Id, Name, or Status which is not the data but the attribute names, all records are always returned.
Record 1
{
Id: 1,
Name: "James",
Status: "None"
}
Record 2
{
Id: 2,
Name: "Paul",
Status: "None"
}
How can I modify a JSON string so that
{ Id: 2, Name: "Paul", Status: "None"}
will become
{ 2, "Paul", "None"}
Your question is a bit unclear (and I'm afraid Matthias' edit made that matter worse).
{ Id: 1, Name: "James", Status: "None" } is not a valid JSON string, but it is a valid Javascript object. JSON strings need to have their values within quotes.
If you are indeed dealing with a JSON string, with quoted properties, and you simply want the output you've requested, you could do something like this:
var person = '{ "Id": 1, "Name": "James", "Status": "None" }';
person = person.replace(/\s*"[^"]+"\s*:/g,"");
// > person = '{ 1, "James", "None" }'
If you are dealing with a Javascript object, a simple way of getting the values without the property names would be to do something like this:
var person = { Id: 1, Name: "James", Status: "None" };
person = Object.keys(person).map(function(k) { return person[k] }).join(',');
// > person = '1,James,None'
Both options will give you a string that you could search for just the values you're interested in. In the latter scenario, you'd need to add some formatting to turn the outcome into exactly what you have requested, but then given the question I'm assuming presentation is not a big deal.
However, if at all possible, I think your code would much more closely match your intentions if you instead modified the search algorithm to inspect values and not entire objects. You haven't shown us any of the code doing the searching, though, so I can't really add suggestions for that at this point.

Categories

Resources