sorting json object based on attribute - javascript

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);

Related

Filter JSON object array on multiple values or arguments javascript

users = [
{
"username": "Alice",
"firstName": "Alice-U",
"lastName": "Wonderland"
},
{
"username": "bob",
"firstName": "Bob-u",
"lastName": "Builder",
},
{
"username": "charly",
"firstName": "Charly-u",
"lastName": "Brown",
}
]
I want to be able to filter this array on multiple values like:
Search Criteria: { "username" : "Alice" } should return:
{
"username": "Alice",
"firstName": "Alice-U",
"lastName": "Wonderland"
}
Similary for: { "username" : "charly", "firstName": "Charly-u" } should return :
{
"username": "charly",
"firstName": "Charly-u",
"lastName": "Brown",
}
with exact string matching using javaScript or jQuery.
You can employ .every to check that each of the criteria keys matches:
function filterBy(list, criteria) {
return list.filter(candidate =>
Object.keys(criteria).every(key =>
candidate[key] == criteria[key]
)
);
}
let users = [
{ "username": "Alice", "firstName": "Alice-U", "lastName": "Wonderland" },
{ "username": "bob", "firstName": "Bob-u", "lastName": "Builder" },
{ "username": "charly", "firstName": "Charly-u", "lastName": "Brown" }
];
console.log(filterBy(users, { "username" : "Alice" }));
console.log(filterBy(users, { "username" : "charly", "firstName": "Charly-u" }));
Why not Array.prototype.filter()? to filter only the element that has username="Alice". By the way you can add multiple object keys inside your filter's arrow function while filtering array of object. For example:
user.username ==='Charly' && firstName==='Charly-u'
users = [{
"username": "Alice",
"firstName": "Alice-U",
"lastName": "Wonderland"
},
{
"username": "bob",
"firstName": "Bob-u",
"lastName": "Builder",
},
{
"username": "charly",
"firstName": "Charly-u",
"lastName": "Brown",
}
];
result = users.filter(user => user.username ==='Alice');
console.log(result);
can’t it be just a function with for loop?
//call
this.filterIt( ‘username’ , ‘Alice’, users);
//function
Function filterIt (key, value, arr){
result = [];
for ( a in arr){
if (a[key] == value) result.push(a);
}
return result;
}
You can write it in the following way. If you want to do exact search write a search function like this:
function search(term) {
return users.filter(({username, firstName, lastName}) => {
return username.toLowerCase() === term.toLowerCase() ||
firstName.toLowerCase() === term.toLowerCase() ||
lastName.toLowerCase() === term.toLowerCase()
})
}
Instead of comparing each key one can iterate all object properties using object.keys.
If you want to match each anything use following function
function search(term) {
return users.filter(({username, firstName, lastName}) => {
return username.toLowerCase().indexOf(term.toLowerCase()) > -1 ||
firstName.toLowerCase().indexOf(term.toLowerCase()) > -1 ||
lastName.toLowerCase().indexOf(term.toLowerCase()) > -1
})
}
This will even match searchTerm anywhere. Like if you use this as search('al'). It will return the first object, whereas the first function will need exact string like search('alice') to work.
const users = [{
"username": "Alice",
"firstName": "Alice-U",
"lastName": "Wonderland"
},
{
"username": "bob",
"firstName": "Bob-u",
"lastName": "Builder",
},
{
"username": "charly",
"firstName": "Charly-u",
"lastName": "Brown",
}
]
function searchFull(term) {
return users.filter(({
username,
firstName,
lastName
}) => {
return username.toLowerCase() === term.toLowerCase() ||
firstName.toLowerCase() === term.toLowerCase() ||
lastName.toLowerCase() === term.toLowerCase()
})
}
function search(term) {
return users.filter(({
username,
firstName,
lastName
}) => {
return username.toLowerCase().indexOf(term.toLowerCase()) > -1 ||
firstName.toLowerCase().indexOf(term.toLowerCase()) > -1 ||
lastName.toLowerCase().indexOf(term.toLowerCase()) > -1
})
}
console.log(searchFull('alice'))
console.log(search('al'))

Sorting array is not happening

I have an array like this and I wnat to ignore first two object and then sort the based on its ISD code in ascdeing order.
My data
"Output" :
[{
Name:"Country"
},{
Name :"CODE"
},
{
"Name" : "Alex",
"Country" :"India",
"CODE": "91"
},{
"Name" : "David",
"Country" : "USA",
"CODE": "1"
},{
"Name" :"Ravi",
"Country" : "NZ"
"CODE": "61"
},{
"Name" :"Smith",
"Country" : "AUS"
"CODE": "64"
}
]
What I am trying here is
var sortedData = sortByKey(output,"CODE")
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));
});
}
But it is rearranging the data rendomly. CAn anyone help me what is going wrong here.
You coudld take localeCompare with some options for sorting numerical values in the right order.
function sortByKey(array, key) {
var temp = array.slice(2);
temp.sort(function (a, b) {
return (a[key] || '').localeCompare(b[key] || '', undefined, { numeric: true, sensitivity: 'base' });
});
return array.slice(0, 2).concat(temp);
}
var array = [{ Name: "Country" }, { Name: "CODE" }, { Name: "Alex", Country: "India", CODE: "2" }, { Name: "David", Country: "USA", CODE: "1" }, { Name: "Ravi", Country: "NZ", CODE: "11" }, { Name: "Smith", Country: "AUS", CODE: "24" }];
console.log(sortByKey(array, "CODE"));
.as-console-wrapper { max-height: 100% !important; top: 0; }
This is working perfectly. If you are looking for numeric sort use parseFloat
If you don't need the data with CODE key use below method
`
var JSON = {
"Output": [
{Name: "Country"},
{Name: "CODE"},
{"Name": "Alex","Country": "India","CODE": "91"},
{"Name": "David","Country": "USA","CODE": "1"},
{"Name": "Ravi","Country": "NZ","CODE": "61"},
{"Name": "Smith","Country": "AUS","CODE": "64"}]
}
var sortedJSON = sortByKey(JSON.Output, "CODE");
console.log(sortedJSON);
function sortByKey(array, key) {
for (var obj in array) {
if(array[obj][key] === undefined) {
delete array[obj];
}
}
return array.sort(function (a, b) {
if(a[key] && b[key]){
var x = parseInt(a[key]);
var y = parseInt(b[key]);
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
});
}
If you want to keep the objects without code use the one below
var JSON = {
"Output": [
{Name: "Country"},
{Name: "CODE"},
{"Name": "Alex","Country": "India","CODE": "91"},
{"Name": "David","Country": "USA","CODE": "1"},
{"Name": "Ravi","Country": "NZ","CODE": "61"},
{"Name": "Smith","Country": "AUS","CODE": "64"}]
}
var sortedJSON = sortByKey(JSON.Output, "CODE");
console.log(sortedJSON);
function sortByKey(array, key) {
return array.sort(function (a, b) {
if(a[key] && b[key]){
var x = parseInt(a[key]);
var y = parseInt(b[key]);
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
}
});
}
This should works, hope it helps!
var data = [
{ "Name": "Country" },
{ "Name": "CODE" },
{ "Name": "Alex", "Country": "India", "CODE": "91" },
{ "Name": "David", "Country": "USA", "CODE": "1" },
{ "Name": "Ravi", "Country": "NZ", "CODE": "61" },
{ "Name": "Smith", "Country": "AUS", "CODE": "64" }
];
var sortedJSON = sortByKey(data, "CODE");
function sortByKey(array, key) {
var others = [], result;
result = array.filter(function(o) {
if (!o[key]) others.push(o);
return (o[key]);
}).sort(function(a, b) {
var x = a[key], y = b[key];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
return others.concat(result);
}
console.log(sortedJSON);

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 });

How to better structure an Array of Arrays in JSON

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);

Categories

Resources