Rank grades as object values from highest to lowest - javascript

I want to get the first name and the gwa from each object, then arrange them according to their gwa from highest to lowest. I got the "getting the first name and gwa" part but I don't know how to arrange them according to their gwa.
I tried to use sort() but I seems to have used it in a wrong way. Can anyone please help me?
const students = [
{
firstName: "Jose",
lastName: "Valenci",
gender: "male",
gwa: 98,
interest: "tennis"
},
{
firstName: "Debby",
lastName: "Smith",
gender: "female",
gwa: 96,
interest: "singing"
},
{
firstName: "Zaira",
lastName: "Pay",
gender: "female",
gwa: 93,
interest: "crafts"
}];
const basedOnGwa = students.map ((name,grade) => {
let{lastName} = name;
let {gwa} = grade;
grade = grade.sort(grade1 => {
let {gwa} = grade1;
return grade1;
});
return grade();
})
console.log(basedOnGwa);

You can try the following code:
const students = [
{
firstName: "Jose",
lastName: "Valenci",
gender: "male",
gwa: 98,
interest: "tennis"
},
{
firstName: "Debby",
lastName: "Smith",
gender: "female",
gwa: 96,
interest: "singing"
},
{
firstName: "Zaira",
lastName: "Pay",
gender: "female",
gwa: 93,
interest: "crafts"
}];
var basedOnGwa = students.reduce((arr,v,i)=>{
return arr.concat({'firstName':v.firstName,'gwa':v.gwa});
},[]);
basedOnGwa.sort((a,b)=>{
return b.gwa - a.gwa;
})
console.log(basedOnGwa);
EDIT
If you want to use map instead of reduce you can follow the following code:
const students = [
{
firstName: "Jose",
lastName: "Valenci",
gender: "male",
gwa: 98,
interest: "tennis"
},
{
firstName: "Debby",
lastName: "Smith",
gender: "female",
gwa: 96,
interest: "singing"
},
{
firstName: "Zaira",
lastName: "Pay",
gender: "female",
gwa: 93,
interest: "crafts"
}];
var basedOnGwa = students.map((v,i)=>{
return {'firstName':v.firstName,'gwa':v.gwa};
});
basedOnGwa.sort((a,b)=>{
return b.gwa - a.gwa;
})
console.log(basedOnGwa);

Related

How do I create a filter function javascript [duplicate]

This question already has answers here:
How to filter object array based on attributes?
(21 answers)
Closed 9 months ago.
Does someone know how to write this code?
On clicking the button, create a new table from people table, which will only contain people whose age is greater than 18 . Display the resulting array in the console
const people = [
{
firstname: "Dreddy",
lastname: "Nussgen",
age: 70,
},
{
firstname: "Yves",
lastname: "Sear",
age: 49,
},
{
firstname: "Marcel",
lastname: "Cowderay",
age: 59,
},
{
firstname: "Dag",
lastname: "Binnall",
age: 31,
},
{
firstname: "Horten",
lastname: "Claesens",
age: 75,
},
{
firstname: "Charmian",
lastname: "Harnes",
age: 10,
},
{
firstname: "Sean",
lastname: "Littlejohns",
age: 37,
},
{
firstname: "Hazlett",
lastname: "Sprouls",
age: 87,
},
{
firstname: "Marcel",
lastname: "Hasted",
age: 66,
},
{
firstname: "Cary",
lastname: "Summerson",
age: 15,
},
{
firstname: "Feodor",
lastname: "Ollett",
age: 56,
},
{
firstname: "Kelly",
lastname: "Ranahan",
age: 62,
},
{
firstname: "Madelene",
lastname: "Davie",
age: 14,
},
{
firstname: "Bent",
lastname: "Karpe",
age: 82,
},
{
firstname: "Reinaldo",
lastname: "Grimbleby",
age: 81,
},
];
You can use Array.prototype.filter() combined with Destructuring assignment
Code:
const people = [{firstname: 'Dreddy',lastname: 'Nussgen',age: 70,},{firstname: 'Yves',lastname: 'Sear',age: 49,},{firstname: 'Marcel',lastname: 'Cowderay',age: 59,},{firstname: 'Dag',lastname: 'Binnall',age: 31,},{firstname: 'Horten',lastname: 'Claesens',age: 75,},{firstname: 'Charmian',lastname: 'Harnes',age: 10,},{firstname: 'Sean',lastname: 'Littlejohns',age: 37,},{firstname: 'Hazlett',lastname: 'Sprouls',age: 87,},{firstname: 'Marcel',lastname: 'Hasted',age: 66,},{firstname: 'Cary',lastname: 'Summerson',age: 15,},{firstname: 'Feodor',lastname: 'Ollett',age: 56,},{firstname: 'Kelly',lastname: 'Ranahan',age: 62,},{firstname: 'Madelene',lastname: 'Davie',age: 14,},{firstname: 'Bent',lastname: 'Karpe',age: 82,},{firstname: 'Reinaldo',lastname: 'Grimbleby',age: 81,},]
const result = people.filter(({ age }) => age > 18)
console.log(result)

lodash find returns only one result

I'm using lodash find, and on my test, it is only returning one result, is this the expected response? how to find all instances?
var users = [
{ firstName: "John", lastName: "Doe", age: 28, gender: "male" },
{ firstName: "Jane", lastName: "Doe", age: 5, gender: "female" },
{ firstName: "Jim", lastName: "Carrey", age: 54, gender: "male" },
{ firstName: "Kate", lastName: "Winslet", age: 40, gender: "female" }
];
var encontre = _.find(users, { lastName: "Doe" })
console.log("usuario encontre::", encontre)
response
usuario encontre:: { firstName: 'John', lastName: 'Doe', age: 28,
gender: 'male' }
so how to seethe 2 users with lastName: Doe?
thanks
Try with _.filter as _.find returns the first matched element.
_.filter will return an array of all matched elements.
var users = [
{ firstName: "John", lastName: "Doe", age: 28, gender: "male" },
{ firstName: "Jane", lastName: "Doe", age: 5, gender: "female" },
{ firstName: "Jim", lastName: "Carrey", age: 54, gender: "male" },
{ firstName: "Kate", lastName: "Winslet", age: 40, gender: "female" }
];
var encontre = _.filter(users, { lastName: "Doe" })
console.log("usuario encontre::", encontre)
jsfiddle for ref : https://jsfiddle.net/c_Dhananjay/b6ngxhvp/

How to get the index of an object in an array of objects when it matches completely javascript

I have an array of objects and I would like to get the index of the object in the array when I get a match.
I have the array as follows:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
.....
];
Currently I am using indexOf which worked initially and now it doesn't work properly. It returns -1.
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.indexOf(find); // should return 1.
The whole should match in the array and should return the index of that object. How can I achieve this? Should I be using some() ?
Thank you
You can use .find instead of indexOf as 2 objects are never equal ( as they point to different reference in memory ) which is what you seem to pass as an argument.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let found = x.find(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(found);
To find the index, you can use .findIndex method instead.
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let foundIndex = x.findIndex(function(item) {
// you can use the condition here
return item.info.id === 564;
});
console.log(foundIndex);
Objects cannot be compared by traditional equality in JavaScript. Instead, use the ES6 findIndex method to compare each object's properties with the desired values. Here is an example:
let x = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}}
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = x.findIndex(element => element.info.id === find.info.id); // index === 1
The id value seems to be sufficient to identify an object in your scenario; if you need to compare more properties, you could obviously add additional equality checks (e.g., element.name === find.name) with the && operator.
If we live in the _.lodash world than this works since lodash would go deep on objects:
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, age: 22, gender: "female"}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
let find = {name: "maggie", info: { id: 234, gender: "female", age: 22}};
let index = _.findIndex(data, (i) => _.isEqual(i, find))
console.log(index) // 1
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
A more brutish approach which obviously it is not performant
and as pointed out wont work if the order of the props is different.
let data = [
{name: "emily", info: { id: 123, gender: "female", age: 25}},
{name: "maggie", info: { id: 234, gender: "female", age: 22}},
{name: "kristy", info: { id: 564, gender: "female", age: 26}},
];
var objectJSONs = data.map((i) => JSON.stringify(i))
let myJSON = JSON.stringify({name: "maggie", info: { id: 234, gender: "female", age: 22}});
let index = objectJSONs.indexOf(myJSON)
console.log(index) // 1
You can make use of underscore _.isEqual for Object comparison and some() or any looping mechanism to iterate the array.
let iFoundIndex = -1;
let bFound = x.some((data,index) => {
if(_.isEqual(data,find){
iFoundIndex = index;
return true;
}
return false;
}
//console.log(iFoundIndex);

Grouping by multiple fields per object

I am trying to determine the best data-type to sort an array of objects, into groups defined by properties. I have an array of objects, like so:
var people = [
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Frank',
gender: 'Male',
age: 22
},
{
name: 'Gary',
gender: 'Male',
age: 21
},
{
name: 'Maria',
gender: 'Female',
age: 20
},
{
name: 'Hannah',
gender: 'Female',
age: 21
},
{
name: 'Pete',
gender: 'Male',
age: 20
}
];
I need to group these objects into an arbitrary-defined group. E.g.:
Group 1: gender
Group 2: age
(This can be defined by the server and can change to contain a third group if we wish.)
Which then gives me (visually):
Male:
21:
Gary
22:
Pete
Frank
Female
20:
Samantha
Maria
21:
Hannah
I think the appropriate data type would be an object of objects. I.e.:
{
Male: {
21: {
[
{
name: 'Gary',
gender: 'Male',
age: 21
}
]
},
22: {
[
{
name: 'Pete',
gender: 'Male',
age: 22
},
{
name: 'Frank',
gender: 'Male',
age: 22
}
]
}
},
Female: {
20: {
[
{
name: 'Samantha',
gender: 'Female',
age: 20
},
{
name: 'Maria',
gender: 'Female',
age: 20
}
]
},
21: {
[
{
name: 'Hannah',
gender: 'Female',
age: 21
}
]
}
}
}
But I cannot work out, for the life of me, an appropriate algorithm to sort these objects into a data-type which represents the above.
There is a useful utility in underscore.js called _.groupBy(arr, callback) which I can use as follows:
_.groupBy(people, function (person) {
var props = ['gender', 'age'], // server-defined
prop = [];
for (var i = 0, length = props.length; i < length; i++) {
prop.push(person[props[i]]);
}
return prop.join('|');
});
This gives me a 1-depth object which I can use a for...in loop to iterate over the keys, and loop through to build the object above, but it's that bit of the code I'm stuck on.
The returned object would be:
{
"Male|22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
],
"Female|20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"Male|21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"Female|21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
],
"Male|20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
]
}
I'm thinking of then looping through each key in the object, splitting at the pipe (|) and using recursion to construct a new object of objects containing the groups/array of data.
That's such a horrendous way of achieving this but I have no idea how to do it otherwise.
Is there a better way I'm missing?
Maybe this helps you. It utilises an array with the properties of the object and the result is grouped by the content of the properties.
The forEach loop iterates over the data. The reduce loop is for generating grouped properties for every given group and if it is the last one it returns an array, if not already there.
The last step is to push the value of one of people to the array.
var people = [{ name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }],
groups = ['gender', 'age'],
grouped = {};
people.forEach(function (a) {
groups.reduce(function (o, g, i) { // take existing object,
o[a[g]] = o[a[g]] || (i + 1 === groups.length ? [] : {}); // or generate new obj, or
return o[a[g]]; // at last, then an array
}, grouped).push(a);
});
document.write('<pre>' + JSON.stringify(grouped, 0, 4) + '</pre>');
you can use lodash
groupBy(people, (item) => item.age + item.gender);
I realy don't understand why people always use frameworks for that kind of things.
Vanilla is faster and this is not too hard to code...
var people = [ { name: 'Pete', gender: 'Male', age: 22 }, { name: 'Samantha', gender: 'Female', age: 20 }, { name: 'Frank', gender: 'Male', age: 22 }, { name: 'Gary', gender: 'Male', age: 21 }, { name: 'Maria', gender: 'Female', age: 20 }, { name: 'Hannah', gender: 'Female', age: 21 }, { name: 'Pete', gender: 'Male', age: 20 }];
var grouped = {}; // final object
for (var i=0,len=people.length,p;i<len;i++) { // faster than .forEach
p = people[i];
if (grouped[p.gender] === undefined) // twice faster then hasOwnProperty
grouped[p.gender] = {};
if (grouped[p.gender][p.age] === undefined)
grouped[p.gender][p.age] = [];
grouped[p.gender][p.age].push(p); // your groupby is HERE xD
}
document.getElementById('grouped').innerHTML = JSON.stringify(grouped, null, 2)
<pre id="grouped"></pre>
I'm going to disagree with you about your expected output. I think you should just have an object with Male and Female array properties and use this code to populate the arrays:
var obj = people.reduce(function (p, c, i) {
p[c.gender].push(c);
return p;
}, { Male: [], Female: [] });
If you want to then filter those arrays you can write functions like this:
function getMaleByAge(obj, age) {
return obj.Male.filter(function (el) {
return el.age === age;
})
}
getMaleByAge(obj, 21); // { name: "Gary", gender: "Male", age: 21 }
DEMO
Using _.groupBy & _.map
var output = _.map(_.groupBy(people, 'gender'),function(obj, key){
var temp = {};
temp[key] = _.groupBy(obj, 'age')
return temp;
});
console.log(JSON.stringify(output, null,' '))
Will give following output
[{
"Male": {
"20": [
{
"name": "Pete",
"gender": "Male",
"age": 20
}
],
"21": [
{
"name": "Gary",
"gender": "Male",
"age": 21
}
],
"22": [
{
"name": "Pete",
"gender": "Male",
"age": 22
},
{
"name": "Frank",
"gender": "Male",
"age": 22
}
]
}
},
{
"Female": {
"20": [
{
"name": "Samantha",
"gender": "Female",
"age": 20
},
{
"name": "Maria",
"gender": "Female",
"age": 20
}
],
"21": [
{
"name": "Hannah",
"gender": "Female",
"age": 21
}
]
}
}
]

Get two fileds from Array result

My service give result as follows
$scope.ListOfPeople = [
{ PersonID: 10, FirstName: "John", LastName: "Smith", Sex: "Male" },
{ PersonID: 11, FirstName: "James", LastName: "Last", Sex: "Male" },
{ PersonID: 12, FirstName: "Mary", LastName: "Heart", Sex: "Female" },
{ PersonID: 13, FirstName: "Sandra", LastName: "Goldsmith", Sex: "Female" },
{ PersonID: 14, FirstName: "Shaun", LastName: "Sheep", Sex: "Male" },
{ PersonID: 15, FirstName: "Nicola", LastName: "Smith", Sex: "Male" }
];
I need to customise my datasource as follows
$scope.output= [
{ PersonID: 10, FirstName: "John" },
{ PersonID: 11, FirstName: "James" },
{ PersonID: 12, FirstName: "Mary" },
{ PersonID: 13, FirstName: "Sandra" },
{ PersonID: 14, FirstName: "Shaun" },
{ PersonID: 15, FirstName: "Nicola" }
];
What is the best way to do this in angularjs
You can use map to achieve your goal. Take in account that the map creates new array.
$scope.output = $scope.ListOfPeople.map(function(item){
return {
PersonID: item.PersonID,
FirstName: item.FirstName
};
});
I don't think you need to create a new array to reshape it's elements. Just delete unwanted properties from your elements.
//Iterate through the array
$scope.listOfPeople.forEach(function(obj){
//Iterate through properties
for (var property in obj) {
if (['PersonId', 'FirstName'].indexOf(property) < 0) //Delete anything you don't name here
delete obj[property];
}
})

Categories

Resources