Construct a JavaScript object dynamically - javascript

I want to populate an array of objects, so that the array should be attached to a grid. This is the format that I require:
data.push({ id: 1, values: { "country": "uk", "age": 33, "name": "Duke", "firstname": "Patience", "height": 1.842, "email": "patience.duke#gmail.com", "lastvisit": "11\/12\/2002" } });
I have key-value pairs of values, I am not sure exactly how would I be constructing the above object in a loop...??
EDIT:
I have this so far, but I am only adding values, not their respective keys:
var recordValues = [];
//for loop iterator
recordValues.push(colValues[colCount]);
//end for
data.push({ id: recordID, values: recordValues });
colValues contain the following: "uk", 33, "Duke"...all the possible values in an object..

If understand you correctly:
var data = [];
for (var i = 0; i < people.length; i++) {
var person = people[i];
data.push({
id : i + 1,
values : {
country : person.country,
age : person.age,
name : person.surname,
firstname : person.firstname,
height : person.height,
email : person.email,
lastvisit : person.lastvisit
}
});
}

for (var key in keyValuePairs) {
if (keyValuePairs.hasOwnProperty(key)) {
data.push({ id: key, values:keyValuePairs[key]);
}
}
hasOwnProperty filters out prototype properties

You could do something like this:
var recordValues = [];
for (var value in colValues) {
recordValues.push(colValues[value]);
}
data.push({ id: recordID, values: recordValues });

Related

Javascript - Create and populate associative array containing sub arrays

I'm trying to collate some data. I would like to populate an array containing sub arrays, for example, I have some json data that I am iterating over:
{
"name": "name1",
"prices": "209.67"
},
{
"name": "name1",
"prices": "350"
},
{
"name": "name2",
"price": "195.97"
},
I would like to create an array that ends up looking something like the following:
myArray['name1']prices[0] = 209.67,
prices[1] = 350,
['name2']prices[0] = 195.97
I thought that the code below would achieve what I wanted but it doesn't work. It throws an exception. It doesn't seem to recognise the fact that the prices are an array for a given index into the main array. Instead the prices appear at the same level as the names. I want the main array for a given name to contain an inner array of prices.. Does anybody have any idea how I could modify to make this work?
function doStuff() {
var cryptoData = getData();
var datasetValues = {};
datasetValues.names = [];
datasetValues.names.prices = [];
for (var result = 0; result < cryptoData.length; result++) {
var data = cryptoData[result];
if (datasetValues.names.indexOf(data.cryptoname) === -1)
{
datasetValues.names.push(data.cryptoname);
}
// This works
//datasetValues.names.prices.push(data.prices);
// This doesn't!
datasetValues.cryptoNames[data.cryptoname].prices.push(data.prices);
}
}
You could reduce the array by using an object and take a default object if the property is not set. Then push the price.
var data = [{ name: "name1", price: "209.67" }, { name: "name1", price: "350" }, { name: "name2", price: "195.97" }],
result = data.reduce((r, { name, price }) => {
r[name] = r[name] || { name, prices: [] };
r[name].prices.push(+price);
return r;
}, Object.create(null));
console.log(result);
Try this
function parseData(input){
return input.reduce(function(o,i){
o[i.name] = {};
if(!o[i.name]['prices']){
o[i.name]['prices'] = [];
}
o[i.name]['prices'].push(i.prices);
return o;
},{});
}

loop through objects and find specified properties

I have an array of objects. A typical object looks like:
{
id: x
name: y
employeeInfo: {
employeeNumber: x
startDate: x
}
salary: x
}
Now I'm trying to loop through it and get the name, employeeNumber and salary.
My column variable, to be used in the loop, is:
public columns: Array<any> = [
{title: 'id', name: 'id'},
{title: 'employeeInfo.employeeNumber', name: 'employeeInfo.employeeNumber'},
{title: 'salary', name: 'salary'}]
I'm trying to loop with
item[column.name]
but of course this would result in item['emplyeeInfo.employeeNumber'], which would result in a undefined.
Can someone help?
You can split the column name and reduce, like:
column.name.split('.').reduce((res, part) => res[part], item)
split returns an array (in our case ['employeeInfo', 'employeeNumber']) so we can reduce that array using the item as the initialValue.
The reduce() method applies a function against an accumulator and each
element in the array (from left to right) to reduce it to a single
value.
Something like this:
var employees = [
{
id: 1,
name: 'Charlie',
employeeInfo: {
employeeNumber: 123,
startDate: '2017-01-23'
},
salary: 2500
},
{
id: 2,
name: 'John',
employeeInfo: {
employeeNumber: 456,
startDate: '2017-02-26'
},
salary: 3500
}
];
var columns = [
{title: 'id', name: 'id'},
{title: 'employeeInfo.employeeNumber', name: 'employeeInfo.employeeNumber'},
{title: 'salary', name: 'salary'}
];
function buildTable() {
var table = $("<table>");
var header = $("<tr>");
for(var i = 0; i < columns.length; i++) {
header.append("<th>" + columns[i].title + "</th>");
}
table.append(header);
for(var i = 0; i < employees.length; i++) {
var employee = employees[i];
var row = $("<tr>");
for(var y = 0; y < columns.length; y++) {
var properties = columns[y].name.split('.');
var value = employee;
for(var x = 0; x < properties.length; x++) {
value = value[properties[x]];
}
row.append("<td>" + value + "</td>");
}
table.append(row);
}
$("#result").append(table);
}
buildTable();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"></div>
Can't you just parse/split the name on the dot and for each part, you get the object, fetch its property and reiterate while there is a next property to fetch?
I ended up using a "simplify" approach. i.e. filter through the array, grab what I need, put it in a new object, put it in a temporary array and finally replace the complex array with the simple array.
try this:
var myObject = {
id: "x",
name: "y",
employeeInfo: {
employeeNumber: "inner employeeNumber",
startDate: "inner date",
},
salary: "x"
}
for(var id in myObject) {
if(typeof myObject[id] === "object") {
for(var innerId in myObject[id]){
console.log(innerId + ": " + myObject[id][innerId]);
}
} else {
console.log(id + " " + myObject[id]);
}
}

How to convert two arrays to a key-value pair and append them to an array

I am working on a project in which I need an array like this:
user = [{
"name": "foo",
"email": "foo#foo.com"
},{
"name": "bar",
"email": "bar#bar.com"
},]
the values name and email are in two separate arrays, like:
names=[foo,bar];
mails=[foo#foo.com,bar#bar.com]
How do I convert these two arrays in a single array of objects with predefined keys name and email?
I am trying something like this:
var user = [];
for(var i=0; i<names.length; i++) {
user[i].name = names[i];
user[i].email = mails[i];
}
but this raises an error that name property is not defined.
You just have to push an object composed of mames and email this way
var names=["foo","bar"];
var mails=["foo#foo.com","bar#bar.com"];
var users = [];
for(var i=0; i<names.length; i++) users.push({"name" : names[i], "email" : mails[i]});
console.log(users);
Run:
[ { name: 'foo', email: 'foo#foo.com' },
{ name: 'bar', email: 'bar#bar.com' } ]

JSON - array of objects into objects of arrays

I have a series of JSON entries:
[{"num": "1","name_A": "Alex" ,"name_B": "Bob"}, {"num": "2","name_A": "Anne" ,"name_B": "Barbra"}]
I am trying to convert this array of Objects as painlessly as possible into two objects - one with title name_A, and the second with the title name_B. Objects have to contain the title and an array of matching num-name pairs:
[{title: "name_A", names:[{"1", "Alex}, {"2", "Anne"}]}, {title:"name_B", names: [{"1", "Bob"}, {"2", "Barbra"}]}]
At first I tried simply to create two objects by reducing the array of object twice, once for name_A and second time for name_B and later glue everything together:
// get 'names' array
var name_A = objArray.reduce(function(memo, curr) {
memo.push({curr.num, curr.name_A})
return memo;
}, []);
But even this is failing. Why there is no push method for memo if I initialize reduce with an empty array?
And second question, am I on a right track or is there a better way to achieve this?
Comments inline, made a few minor corrections to the expectations.
var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }]
var output = input.reduce(function (a, b) {
// construct new objects and set their properties
var i = {};
i[b.num] = b.name_A;
var j = {};
j[b.num] = b.name_B;
// add them to our collection elements
a[0].names.push(i);
a[1].names.push(j);
return a;
// initializing our collection
}, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]);
// pretty print our output
console.log(JSON.stringify(output, null, " "))
var input = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }]
var output = input.reduce(function (a, b) {
// construct new objects and set their properties
var i = {};
i[b.num] = b.name_A;
var j = {};
j[b.num] = b.name_B;
// add them to our collection elements
a[0].names.push(i);
a[1].names.push(j);
return a;
// initializing our collection
}, [{ title: "name_A", names: [] }, { title: "name_B", names: [] }]);
so.log(output)
<pre id="output"></pre>
<script>
var so = {
log: function(o) {
document.getElementById("output").innerHTML = JSON.stringify(o, null, " ")
}
}
</script>
The problem with your code is that { curr.num, curr.name_A } is not a valid object, it's missing the property names. I've added properties num and name in my code below.
var name_A = [];
var name_B = [];
objArray.forEach(function(curr) {
name_A.push({num: curr.num, name: curr.name_a});
name_B.push({num: curr.num, name: curr.name_B});
});
var result = [
{ title: "name_A" }, names: name_A },
( title: "name_B" }, names: name_B }
];
Also, if you want to make an array out of the results of looping over an array, you should use .map rather than .reduce.
Assuming only property num is fixed. All other properties are treated as data, like name_A or name_B.
var a = [{ "num": "1", "name_A": "Alex", "name_B": "Bob" }, { "num": "2", "name_A": "Anne", "name_B": "Barbra" }],
result = [];
a.forEach(function (el) {
var num = el.num;
Object.keys(el).forEach(function (k) {
function tryFindIndexAndSetNames(aa, i) {
if (aa.title === k) {
result[i].names[num] = el[k];
return true;
}
}
if (k !== 'num' && !result.some(tryFindIndexAndSetNames)) {
var o = {};
o[num] = el[k];
result.push({ title: k, names: o });
}
});
});
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

Remove duplicates and merge JSON objects

I have the following JSON object. I need to remove the duplicates and merge the inner object using plain Javascript. How do I go about doing this?
[{
"id" : 1,
"name" : "abc",
"nodes" :[
{
"nodeId" : 20,
"nodeName" : "test1"
}
]
},
{
"id" : 1,
"name" : "abc",
"nodes" :[
{
"nodeId" : 21,
"nodeName" : "test2"
}
]
}]
Following is the object that I expect as output.
[{
"id" : 1,
"name" : "abc",
"nodes" :[
{
"nodeId" : 20,
"nodeName" : "test1"
},
{
"nodeId" : 21,
"nodeName" : "test2"
},
]
}]
Regards.
Shreerang
First turn the JSON into a Javascript array so that you can easily access it:
var arr = JSON.parse(json);
Then make an array for the result and loop through the items and compare against the items that you put in the result:
var result = [];
for (var i = 0; i < arr.length; i++) {
var found = false;
for (var j = 0; j < result.length; j++) {
if (result[j].id == arr[i].id && result[j].name == arr[i].name) {
found = true;
result[j].nodes = result[j].nodes.concat(arr[i].nodes);
break;
}
}
if (!found) {
result.push(arr[i]);
}
}
Then you can create JSON from the array if that is the end result that you need:
json = JSON.stringify(result);
If your string is called input, then this:
var inter = {};
for (var i in input) {
if (!inter.hasOwnProperty(input[i].name)) {
inter[input[i].name] = input[i].nodes;
inter[input[i].name].name = input[i].name;
inter[input[i].name].id = input[i].id;
}
else
inter[input[i].name] = inter[input[i].name].concat(input[i].nodes)
}
results in:
{"abc":[{"nodeId":20,"nodeName":"test1"},{"nodeId":21,"nodeName":"test2"}]}
You can see how I'm using an intermediate object keyed by whatever the match criterion is. It's an object rather than an array as you asked, but you can iterate it anyway. In fact you're probably better off with this structure than the array you asked for.
BTW, I shoved a couple of text-named properties: "id" and "name" into an array there. They don't show up in JSON.stringify but they're there.

Categories

Resources