How to better structure an Array of Arrays in JSON - javascript

In the following JSON object:
var employees = { "accounting" : [ // accounting is an array in employees.
{ "firstName" : "John", // First element
"lastName" : "Doe",
"age" : 23 },
{ "firstName" : "Mary", // Second Element
"lastName" : "Smith",
"age" : 32 }
], // End "accounting" array.
"sales" : [ // Sales is another array in employees.
{ "firstName" : "Sally", // First Element
"lastName" : "Green",
"age" : 27 },
{ "firstName" : "Jim", // Second Element
"lastName" : "Galley",
"age" : 41 }
] // End "sales" Array.
} // End Employees
How do I restructure the object so I can access each employee first name like this:
employees[0].firstName
employees[1].firstName
// etc

It would require restructuring it so that you'd eliminate the "accounting/sales" properties and make employees an Array of Objects.
Example: http://jsfiddle.net/hgMXw/
var employees = [
{
"dept": "accounting", // new property for this object
"firstName": "John",
// First element
"lastName": "Doe",
"age": 23
},
{
"dept": "accounting", // new property for this object
"firstName": "Mary",
// Second Element
"lastName": "Smith",
"age": 32
},
{
"dept": "sales", // new property for this object
"firstName": "Sally",
// Third Element
"lastName": "Green",
"age": 27
},
{
"dept": "sales", // new property for this object
"firstName": "Jim",
// Fourth Element
"lastName": "Galley",
"age": 41
}
]

You can't pivot this like that. Either you move the department as a key in the employee object or you have to access it like employees.accounting[0].firstName.
If you insist on accessing the employee as employees[index], you have to restructure it to:
var employees = [
{ "firstName" : "John", "lastName" : "Doe", "age" : 23, "department" : "accounting" },
{ "firstName" : "...", ..., "department" : "accounting" },
... and so on.
];
and introduce a different way to filter by department.
maybe create a function that loop through the employees array, and copy each element that match the filter into a new array object and return it.
function getAllEmployeesFilteredBy(filterName, filterValue, empArray)
{
var result = [];
for (var i=0; i < empArray.length; i++) {
if (empArray[i][filterName] === filterValue)
//by ref
result[result.length] = empArray[i];
//or if you prefer by value (different object altogether)
//result[result.length] = { "firstName" : empArray[i].firstName, "lastName" : empArray[i].lastName, ... }
}
return result;
}

From jsFiddle
var employees = { "firstName" : "John", // First element
"lastName" : "Doe",
"age" : 23 },
{ "firstName" : "Mary", // Second Element
"lastName" : "Smith",
"age" : 32 }
;
alert(employees);

Related

Filter nested objects by property

I am consuming a (badly designed) API which sends the following response:
{
"0" : {
"name" : "John",
"last_name" : "Doe"
},
"1" : {
"name": "Mary",
"last_name": "Ann"
},
[...]
}
As you may have noticed, it is a large JSON object with nested objects. Since it isn't an array, i can't use .filter(). So, how can i filter this large object by a nested object property (e.g. name or last_name)?
You can make it as array using Object.values(type).flat(). Then it will make the object values as single array.
const input1 = {
"0" : {
"name" : "John",
"last_name" : "Doe"
},
"1" : {
"name": "Mary",
"last_name": "Ann"
}
}
function search(input, key) {
return Object.values(input).flat().filter(({ name }) => name === key);
}
console.log(search(input1, "John"));

conditional operator to check same value in an array then filter it

I have an array with user who has a property with the latitude.
How can i do if i want to create a new array with user who has the same latitude ?
my array looks like this :
let arrayToFilter = [
{
"user1" : {
"profile" : {
"name" : "user1",
"age" : "35",
"gender" : "male",
"latitude" : 57.267801888216965,
"longitude" : 16.451598081831214
}
},
"user2" : {
"profile" : {
"name" : "user2",
"age" : "50",
"gender" : "male",
"latitude" : 37.785834,
"longitude" : -122.406417
}
},
"user3" : {
"profile" : {
"name" : "user3",
"age" : "23",
"latitude" : 37.785834,
"longitude" : -122.406417
}
}
}
]
i´ve tried with this, but this does not seem to work...
let arr = arrayToFilter.filter(child => child.latitude === child.latitude)
the problem is your arrayToFilter, it is an array but it has just one item and inside that object you have a key/value user with the information, thus the steps are the following:
loop over the array.
loop over the keys to get the items
finally loop over the users to get the desired info.
notice that because we are doing a map then another map and then filter we are going to get a similar structure as you gave.
Array -> Array -> UserObject.
let user = {
name: 'test',
latitude: 57.267801888216965
}
let arrayToFilter = [{
"user1": {
"profile": {
"name": "user1",
"age": "35",
"gender": "male",
"latitude": 57.267801888216965,
"longitude": 16.451598081831214
}
},
"user2": {
"profile": {
"name": "user2",
"age": "50",
"gender": "male",
"latitude": 37.785834,
"longitude": -122.406417
}
},
"user3": {
"profile": {
"name": "user3",
"age": "23",
"latitude": 37.785834,
"longitude": -122.406417
}
}
}]
//we have to loop over the array because it is an array of objects and the users are actually inside the object of the first item.
let filtered = arrayToFilter.map(items => {
//here we are going to loop to get the keys and then iti will return us an arrar
//with the items inside, then we can apply the filter.
return Object.keys(items).map(k => items[k]).filter(u => u.profile.latitude === user.latitude)
})
console.log(filtered);
The error with your code is that you are comparing the user to itself. Your filter queries whether the user's latitude is equal to its own latitude, this is true for all users and you will get an array back with all users.
It should instead be:
let arr = arrayToFilter.filter(child => child.latitude === latitudeToCompare)
Where latitudeToCompare is the latitude at which you would like to find users with the same latitude.
If what you are looking for is a "group by" option in Javascript, then as per this Stackoverflow post can be implemented with a slight variation as follows:
var groupBy = function(xs, [min, max]) {
return xs.reduce(function(rv, x) {
(min < rv[x['latitude']] < max || []).push(x);
return rv;
}, {});
};
where xs is the array of user objects, and min/max are the minimum and maximum latitude to create a range or bucket of latitudes.
You should be able to use the above to help you figure out a solution for your problem.

Creating a new object from array of objects and grouping by specific matching key/value

Example of the object data I am dealing with
var myData = [{
"name": "John",
"age": 30,
"interest": "Baseball"
},
{
"name": "Bob",
"age": 21,
"interest": "Baseball"
},
{
"name" : "Sally",
"age" : 29,
"interest": "Tennis"
}]
I am trying to figure out the easiest way to group them by interests. I am open to using lodash or underscore, but I cannot get the final result to look like this....
I want this to be the output:
[{ "Baseball" : [{
"name": "John",
"age" : 30
},
{
"name" : "Bob",
"age" : 21
}]
},
{ "Tennis" : [{
"name" : "Sally",
"age" : 21
}]
}];
Basically, each interest becomes a new object key containing all of the matched values within arrays.
I am having trouble constructing this output. Any assistance would be greatly appreciated. I prefer to use lodash/underscore to keep things very easy.
Thank you!
You could use Array.reduce for this:
var myData = [
{
"name": "John",
"age": 30,
"interest": "Baseball"
},
{
"name": "Bob",
"age": 21,
"interest": "Baseball"
},
{
"name" : "Sally",
"age" : 29,
"interest": "Tennis"
}];
var result = myData.reduce(function(entities, obj) {
entities[obj.interest] = (entities[obj.interest] || []).concat({
name: obj.name,
age: obj.age
});
return entities;
}, {});
console.log(result);
A little bit more general approach:
function groupBy(data, key, tFunc) {
mapFunc = (typeof tFunc === "function")? tFunc: function(o) { return o };
return (Array.isArray(data)?data:[]).reduce(function(entities, o) {
if(o[key]) {
entities[o[key]] = (entities[o[key]] || []).concat(tFunc(o));
}
return entities;
}, {});
}
// test code
var myData = [
{
"name": "John",
"age": 30,
"interest": "Baseball"
},
{
"name": "Bob",
"age": 21,
"interest": "Baseball"
},
{
"name" : "Sally",
"age" : 29,
"interest": "Tennis"
}];
var result = groupBy(myData, "interest", function(o) { return { name: o.name, age: o.age}});
console.log(result);
var result2 = groupBy(myData, "age", function(o) { return o.name});
console.log(result2);
A group-by operation can be done by matching values in a dictionary (hashtable). In JavaScript all objects are dictionaries with property-names as the keys, for values we use arrays.
For example (press the "Run code snippet" button below to see the results):
function groupBy( input, propertyName ) {
var output = {};
for(var i = 0; i < input.length; i++) {
var groupByValue = input[i][propertyName];
if( !(groupByValue in output) ) {
output[ groupByValue ] = [];
}
var dolly = cloneObjectButIgnoreProperty( input[i], propertyName );
output[ groupByValue ].push( dolly );
}
return output;
}
function cloneObjectButIgnoreProperty( value, ignorePropertyName ) {
var dolly = {};
var propertyNames = Object.keys( value );
for( var i = 0; i < propertyNames .length; i++ ) {
var propertyName = propertyNames[i];
if( propertyName == ignorePropertyName ) continue;
dolly[propertyName ] = value[propertyName ];
}
return dolly;
}
var myData = [
{
"name": "John",
"age": 30,
"interest": "Baseball"
},
{
"name": "Bob",
"age": 21,
"interest": "Baseball"
},
{
"name" : "Sally",
"age" : 29,
"interest": "Tennis"
}
];
var groupedByInterest = groupBy( myData, 'interest' );
console.log( "By interest:" );
console.log( groupedByInterest );
var groupedByName = groupBy( myData, 'name' );
console.log( "By name:" );
console.log( groupedByName );
var groupedByAge = groupBy( myData, 'age' );
console.log( "By age:" );
console.log( groupedByAge );
The solution using Array.prototype.reduce() function:
var myData = [{ "name": "John", "age": 30, "interest": "Baseball" }, { "name": "Bob", "age": 21, "interest": "Baseball" }, { "name" : "Sally", "age" : 29, "interest": "Tennis" }],
result = myData.reduce(function (r, o) {
r[o.interest] = r[o.interest] || [];
r[o.interest].push({name: o.name, age: o.age});
return r;
}, {});
console.log(result);
var myData = [{name:"John",age:30,interest:"Baseball"},{name:"Bob",age:21,interest:"Baseball"},{name:"Sally",age:29,interest:"Tennis"}],
result = [],
interests = [...new Set(myData.map(v => v.interest))];
interests.forEach(v => result.push({ [v] : [] }));
myData.forEach((v,i) => result.forEach((c,i) => Object.keys(c)[0] == v.interest ? result[i][v.interest].push({name: v.name, age: v.age}) : c))
console.log(result);

Javascript Object output to Array

This is a very very simple question, but for some reason I'm stuck with it.
How can I take an object like:
var billionaire = {
"10" : {
"firstName" : "Steve",
"lastName" : "Jobs",
"company" : "Apple"
},
"11" : {
"firstName" : "Bill",
"lastName" : "Gates",
"company" : "Microsoft"
},
"12" : {
"firstName" : "Warren",
"lastName" : "Buffet",
"company" : "Berkshire Hathaway"
}
};
And Output it into an array like this using pure javascript
var arr = [
"Steve",
"Bill",
"Warren"
];
I do just need the firstName in the array. Thanks for your help and sorry for the easy question.
You can do
var arr = Object.keys(billionaire).map(function(k){ return billionaire[k].firstName });

sorting json object based on attribute

I have json object array containing firstname, lastname and age. I want to sort array based on age.
<!DOCTYPE html>
<html>
<body>
<h2>Create Object from JSON String</h2>
<p>Original name: <span id="origname"></span></p>
<p>New name: <span id="newname"></span></p>
<p>Age: <span id="age"></span></p>
<script>
var employees = [
{ "firstName" : "John" , "lastName" : "Doe" , "age":"24" },
{ "firstName" : "Anna" , "lastName" : "Smith" , "age":"30" },
{ "firstName" : "Peter" , "lastName" : "Jones" , "age":"45" },
];
document.getElementById("origname").innerHTML=employees[0].firstName + " " + employees[0].lastName;
// Set new name
employees[0].firstName="Gilbert";
document.getElementById("newname").innerHTML=employees[0].firstName + " " + employees[0].lastName;
document.getElementById("age").innerHTML=employees[0].age;
</script>
</body>
</html>
var employees = [{
"firstName": "Anna",
"lastName": "Smith",
"age": "30"
},
{
"firstName": "John",
"lastName": "Doe",
"age": "24"
},
{
"firstName": "Peter",
"lastName": "Jones",
"age": "45"
}
];
function sortByKey(array, key) {
return array.sort(function(a, b) {
var x = a[key];
var y = b[key];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}
people = sortByKey(employees, 'age');
console.log(people);

Categories

Resources