I want to have a JSON object which contains multiple person objects. Is there a better way to format this? What I did below is have a result key which would be an array consisting of arrays (which have the JSON person object inside of the inner array).
{
result: [
[
{
"name": "Josh",
"age": 15
}
],
[
{
"name": "Joe",
"age": 16
}
]
]
}
Then in the for loop I do something like this:
var nameArray = result[0];
for (var i = 0; i < numberOfObjectsInJSONObject; i++) {
newNameArray.push(nameArray[i].firstPerson);
}
No point in having each person object wrapped inside it's own array. Unless there is some other grouping that needs done all you should need is one array that contains all the person objects
result: [
{
"name": "Josh",
"age": 15
},
{
"name": "Joe",
"age": 16
}
]
This array can be sorted by ages or names, filtered etc
If you want to keep object like that, something like this work. pleases try this one
var pList = {
people: [{
'name': 'Josh',
'age': 15
}, {
'name': 'Joe',
'age': 16
}],
animal: [{
'type': 'Dog',
'legs': 4
}, {
'type': 'Bird',
'legs': 2
}]
};
[].forEach.call(pList.people, function(p) {
// can push its value into new array or else
console.log(`${p.name} -- ${p.age}`);
})
//or
pList.animal.forEach(function(a) {
console.log(`${a.type} -- ${a.legs}`)
})
Here is your list of objects:
var a = [];
a.push({ "name" : "Joe", "age" : 16 });
a.push({ "name" : "John", "age" : 17 });
Here is how you can create JSON:
JSON.stringify(a);
Here is the result:
[{"name":"John","age":17},{"name":"Joe","age":16}]
Here is how you can iterate through your array:
for (var i = 0; i < a.length; i++) { console.log(a[i]) }
Related
I have nested employee objects of different, unknown depths. Each object has a children property, which is an array of the employee objects who report to that employee. These child objects have the same attributes as the top level object and may or may not have employee objects in their own children property.
I need to go through each employee object's array of employee objects and add each of those objects to one of two different arrays, depending on whether the object has other employee objects in it's own "children" property. These arrays are also properties of the employee objects. Employees with empty "children" arrays will be added to their parent employee's nonManagersUnder array, while those with objects in their children array will be added to the managersUnder array.
The nested employee objects look like this:
{
id: "n1",
"isActive": true,
age: 38,
name: "Barb Smith",
"phone": "+1 (882) 547-3581",
"hired": "2016-08-08T12:46:19 +07:00",
children: [
{
id: "n10",
"isActive": true,
age: 37,
name: "Elsie MacDonald",
"phone": "+1 (958) 558-2389",
"hired": "2015-08-15T04:44:49 +07:00",
children: [
]
},
{
id: "n11",
"isActive": true,
age: 29,
name: "Peter Chen",
"phone": "+1 (881) 574-3927",
"hired": "2015-02-16T12:11:11 +08:00",
children: [
]
},
{
id: "n12",
"isActive": true,
age: 32,
name: "Ty Wilder",
"phone": "+1 (990) 506-2830",
"hired": "2019-09-17T06:29:16 +07:00",
children: [
]
}
}
This is a very simple example since I didn't want to put something several hundred lines long in my post, but the structure is the same. Just imagine that each of the secondary employee objects has its own children.
You'll notice that the nonManagersUnder and managersUnder arrays are not attributes of the employee objects to start with. That is because in my current solution they are dynamically assigned.
Here is that solution:
countManagers = (employee) => {
let midManagers = []
let nonManagers = []
employee.children.map(child =>{
if(child.children.length == 0) {
nonManagers.push(child);
}else {
midManagers.push(child);
child.children.map(grandChild => {
if(grandChild.children.length == 0){
nonManagers.push(grandChild);
}else {
midManagers.push(grandChild);
grandChild.children.map(greatGrand => {
if(greatGrand.children.length == 0){
nonManagers.push(greatGrand)
} else {
midManagers.push(greatGrand);
greatGrand.children.map(grand3 => {
if(grand3.children.length==0){
nonManagers.push(grand3);
} else {
midManagers.push(grand3);
grand3.children.map(grand4 => {
if(grand4.children.length==0){
nonManagers.push(grand4);
} else {
midManagers.push(grand4);
}
})
}
})
}
})
}
})
}
})
console.log(midManagers);
// console.log(nonManagers);
employee.managersUnder = (midManagers);
employee.nonManagersUnder=(nonManagers)
}
As you can see, it is simply nested map operators and some conditionals, nested to the maximum depth an employee object can be nested. This solution does work, but is very ugly and I'm almost certain there is a better way of doing this. A better solution would work for an object of any depth. This only works for objects where the depth is equal to or less than the number of nested map operators.
I wanted to refresh some recursion stuffs and came out with a solution for you query.
const values = [{
id: "n1",
children: [{
id: "n10",
children: [{
id: "n100",
children: []
}, ]
},
{
id: "n11",
children: []
},
{
id: "n12",
children: []
}
]
}]
const getAllManagers = (employees) => {
return employees.reduce((acc, emp) => {
return acc.concat(emp.children.length > 0 ? [emp, ...getAllManagers(emp.children)] : [])
}, [])
}
const getAllNonManagers = (employees) => {
return employees.reduce((acc, emp) => {
return acc.concat(emp.children.length > 0 ? getAllNonManagers(emp.children) : emp)
}, [])
}
console.log("Managers: ", getAllManagers(values))
console.log("NonManagers:", getAllNonManagers(values))
I have a data set that I'm pulling in from a database. It's one dimensional and I basically need to make it more structured. I refer to it as "flat".
I need to display a heading, and items under that heading that are related to the heading.
The data comes in as having and section_name (the heading) and item_name (items) and other data unique to each item like download URLs etc.
item_name(item)_______section_name(header)
first_________________Funds
second________________Funds
third_________________Funds
fourth________________Literature
fifth_________________Literature
sixth_________________Literature
seventh_______________Literature
eighth________________DueDilligence
I don't know what any of the names will be for the items or sections, or how many items, sections, or items per section. As I said, it's very flat. This needs to be fully dynamic which is why this is complicating things for me.
Here is what I've done.
API call to retrieve data. Store data in a state as an array (it comes in as an array of objects).
I create an empty array to store my newly structured data.
I loop through the data with a foreach.
I create a new object for my new data to add to the new array so I can loop over it later.
I first check to make sure the data exists.
To create the headers I check to see if my new empty array is actually empty OR my section_name is not the same as the last one.(in the original data array I got from the API call)
I store the section_names as an object in the new array (newArray.push(newObject)
I've gotten this far. Now I need to take the item_names that correlates to the section_names and store them in the object under each header name, or at least in the same index.
_generateInfo() {
let dataArray = this.state.stepTwoData
let newArray =[]
dataArray.forEach(function(item, index) {
let newObject = {}
if (index > 0) {
if (newArray.length === 0 || item.investor_portal_section_name !== dataArray[index -1].investor_portal_section_name) {
newObject["name"] = item.investor_portal_section_name
newObject["items"] = []
newArray.push(newObject)
}
})
console.log(newArray)
}
I tried pushing the items to the "number" array on my new object and that doesn't seem to work properly. Sometimes it will duplicate my newObject.name
Checking if the newObject.name === the section_names in the array and push it to the "number" array in my new object just creates new key-value pairs so it's still not correlating.
I tried looping through again in the if statement and if section_name === newObject.name then create a newObject and push it, but it would only push one of the items repeatedly instead of going through all of them.
I need to loop through and create a header (one header per different section_name). Then add each item that corresponds to the section_name to it. like this
[
{section_name(header): "Funds",
items: [
{
name: item_name,
sku: item_sku,
url: item_url
},
{
name: item_name,
sku: item_sku,
url: item_url
}]
},
{section_name(header):"Literature",
items: [
{name: item_name,
sku: item_sku,
url: item_url
},
{
name: item_name,
sku: item_sku,
url: item_url
}]}
]
Using associative array (dictionary) to segregate you data itmes by categories will do the job.
I've drafted some POC code that illustrates the idea. The key element there is buildAssociativeArray function
const raw_data = [
{item_name: "first", section_name: "Funds"},
{item_name: "second", section_name: "Funds"},
{item_name: "third", section_name: "Funds"},
{item_name: "fourth", section_name: "Literature"},
{item_name: "fifth", section_name: "Literature"},
{item_name: "sixth", section_name: "Literature"},
{item_name: "seventh", section_name: "Literature"},
{item_name: "eighth", section_name: "DueDilligence"},
]
function buildAssociativeArray(data) {
const dictionary = {};
for (var i = 0; i < data.length; i++) {
const item = data[i];
const section = item.section_name;
var dictEntry = dictionary[section];
if (!dictEntry) {
dictEntry = [];
dictionary[section] = dictEntry;
}
dictEntry.push({
name: item.item_name,
// other fields like sku: item_sku or url: item_url may follow here
});
}
return dictionary;
}
const dictionary = buildAssociativeArray(raw_data);
console.log(dictionary);
/*
At this point
dictionary == {
"Funds": [
{
"name": "first"
},
{
"name": "second"
},
{
"name": "third"
}
],
"Literature": [
{
"name": "fourth"
},
{
"name": "fifth"
},
{
"name": "sixth"
},
{
"name": "seventh"
}
],
"DueDilligence": [
{
"name": "eighth"
}
]
}
*/
// Associcative array dictionary itself allows to further solve you task using for (var key in dictionary) {...} operator
// If however you need to obtain the data structure looking exactly like the one in your question you may go further with following function
function transformAssociativeArray(dictionary) {
const array = [];
for (var key in dictionary) {
const items = dictionary[key];
const newEntry = {
section_name: key,
items: items,
}
array.push(newEntry);
}
return array;
}
const array = transformAssociativeArray(dictionary);
console.log(array);
/*
At this point
array == [
{
"section_name": "Funds",
"items": [
{
"name": "first"
},
{
"name": "second"
},
{
"name": "third"
}
]
},
{
"section_name": "Literature",
"items": [
{
"name": "fourth"
},
{
"name": "fifth"
},
{
"name": "sixth"
},
{
"name": "seventh"
}
]
},
{
"section_name": "DueDilligence",
"items": [
{
"name": "eighth"
}
]
}
]
*/
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I can ordering a-z using the .sort() method in javascript, but I would get a JSON like this: (With a "A-Z" index containing the result)
data: {
"A": [
{
"name": "Anh Tuan Nguyen",
"age": 28
},
{
"name": "An Nguyen",
"age": 20
},
],
"Z": [
{
"name": "Zue Dang",
"age": 22
},
{
"name": "Zoom Jane",
"age": 30
},
]
}
var names = [{name:"a1"},{name:"a2"},{name:"b1"},{name:"b2"}.....];
var data = {};
for (var i = 0; i < names.length; i++) {
var n = names[i].name.subStr(0,1);
if (data[n] == null)
data[n] = [];
data[n].push(names[i]);
}
There is no way to sort a JSON data structure, however, we can do it by using the following process:
Get your data keys with Object.keys(myResults.data)
Sort you keys
Create a reduce function to transform your ordered keys into an ordered object
The snippet is here, I hope it helps:
var myResults = {
data: {
C: [
{
"name": "Kevin Doe",
"age": 22
}
],
A: [
{
"name": "Alex Doe",
"age": 31,
}
],
B: [
{
"name": "Boris Doe",
"age": 22
},
{
"name": "Birdo Doe",
"age": 30
},
]
}
};
var originalData = myResults.data;
// 1. get the keys
var dataKeys = Object.keys(originalData);
// 2. sort the keys
var sortedKeys = dataKeys.sort();
// 3. create the object again
var orderedData = sortedKeys.reduce(function(result, key) {
return Object.assign(
{},
result,
{ [key]: myResults.data[key] }
);
}, {});
document.getElementById('original').innerHTML = JSON.stringify(originalData);
document.getElementById('sorted').innerHTML = JSON.stringify(orderedData);
h3 {
margin: 0;
}
code {
display: block;
margin-bottom: 15px;
padding: 10px;
background-color: #f9f9f9;
}
<h3>Original Data</h3>
<code id="original"></code>
<h3>Ordered Data</h3>
<code id="sorted"></code>
JavaScript objects are not ordered. If you want to iterate over an object's properties, you can sort the keys and then retrieve your values:
const result = {
data: {
Z: [],
F: [],
A: [],
D: []
}
};
Object
.keys(result.data)
.sort()
.map(key => console.log(key, result.data[key]));
UPDATE:
Exist a JavaScript library that make It possible: Lodash Utilities (https://lodash.com/docs/4.17.4). Contain methods for .sort() JSON (no Arrays) and a method to obtain the JSON for I asked in this question. I only did this:
//First, order my JSON alphabetically with _.sortBy method (I can even order by a nested property in my JSON)
var order = _.sortBy(require('./names'), function (el) { return el.name });
//Second, I group my order result by the first letter of my property 'name' in my JSON
var list = _.groupBy(order, (b) => b.name[0].toUpperCase());
This is my input:
[
{"name":"Mark"},
{"name":"Jul"},
{"name":"Alicia"},
]
This is my output:
[
"A": [
{
"name": "Alicia"
}
],
"J": [
{
"name": "Jul"
},
],
"M": [
{
"name": "Mark"
},
]
I hope this help to somebody!
I got stuck trying to retrive array items. So here is the deal. I have a two dimentional array which has value and key so example of my data is:
[
Object { css="SS", title="Apple"},
Object { css="SS", title="Orange"},
Object { css="SS", title="Banana"}
]
I want to see if an object exists in the array above. And I have no idea why its not working, here is my code to find the object:
jQuery.inArray("Apple", fruits["title"]); //this returns -1 why?
Any ideas how to search two dimensional array?
This is not a 2D array, this is an array of objects, so this should work:
for (var i = 0; i < array.length; i++) {
console.log(array[i].title); //Log the title of each object.
if (array[i].title == "Apple") {
console.log("Found apple!");
}
}
Also, objects are key/val pairs, denoted by key : val, not key = val. Your array has syntax errors and shouldn't run.
To be pedantic, you have an array of objects, not a 2d array. Also your syntax for the object parameters is incorrect.
You can use filter() on the array to find the values:
var array = [
{ css: "SS", title: "Apple"},
{ css: "SS", title: "Orange"},
{ css: "SS", title: "Banana"}
];
var matches = array.filter(function (obj) { return obj.title == "Apple" });
if (matches.length) {
// Apple was in the array...
}
If you have an object like this
var peoples = [
{ "name": "bob", "dinner": "pizza" },
{ "name": "john", "dinner": "sushi" },
{ "name": "larry", "dinner": "hummus" }
];
Ignore what's below. Use the filter method!
peoples.filter(function (person) { return person.dinner == "sushi" });
// => [{ "name": "john", "dinner": "sushi" }]
You can search for people who have "dinner": "sushi" using a map
peoples.map(function (person) {
if (person.dinner == "sushi") {
return person
} else {
return null
}
}); // => [null, { "name": "john", "dinner": "sushi" }, null]
or a reduce
peoples.reduce(function (sushiPeople, person) {
if (person.dinner == "sushi") {
return sushiPeople.concat(person);
} else {
return sushiPeople
}
}, []); // => [{ "name": "john", "dinner": "sushi" }]
I'm sure you are able to generalize this to arbitrary keys and values!
fruits probably is a array, fruits["title"] therefor doesn't exist.
You might want to transform your data:
var fruitTitles = fruits.map(function(f) { return f.title; });
jQuery.inArray("Apple", fruitTitles);
From the jQuery docs:
jQuery.inArray( value, array [, fromIndex ] )
I've never used this method, but a quick guess:
var hasIt = jQuery.inArray({css:"SS",title:"Apple"}, myArray);
As the $.inArray() documentation explains, the first argument to the function is the value to search for. Your array does not have any elements that are equal to the string "Apple" that you have supplied in the first argument because none of your array elements are strings (they're all objects).
The second argument to $.inArray() is supposed to be the array itself, but (assuming fruits is the array you show) fruits["title"] is undefined because your array has no property called "title", only the objects in the array have that property.
Try this instead:
var index = $.inArray("Apple", $.map(fruits, function(el) { return el.title; }));
try this code
var fruits = [
{ css:"SS", title:"Apple"},
{ css:"SS", title:"Orange"},
{ css:"SS", title:"Banana"}
];
jQuery.grep(fruits,function(fruit){return fruit.title == 'Apple'});
I am meeting now the difficult problem for me that hurt my heart,
I want to convert [01] JSON to [02].
[01] JSON :
{locations: [
{
country: "Australia",
area: "NSW",
city: "Gordon"
},
{
country: "Australia",
area: "NSW",
city: "Chatswood"
}
]};
[02] JSON :
{countries: [
{
name: "Australia",
areas: [
{
name: "NSW",
cities: [
{
name: "Gordon"
},
{
name: "Chatswood"
}
]
}
]
}
]}
Since you're going to be doing a bunch of lookups I suggest using a collection of objects rather than your final structure with arrays. You can then either convert it to the final structure or modify code to use it the way it is.
var countries = {};
for (var i=0, loc; loc = locations[i]; i++) {
if (!countries[loc.country]) countries[loc.country] = {};
if (!countries[loc.country][loc.area]) countries[loc.country][loc.area] = [];
countries[loc.country][loc.area].push(loc.city);
}
alert(JSON.stringify(countries));