reduce more than one value - javascript

Is there any way that I can return more than one object with the reduce function? For example, I want to return the oldest age and I have 3 people who are all the same age. See below, thanks!
var dataArray = [
{name: "Roy", age: 24, sex: "M"},
{name: "Ben", age: 25, sex: "M"},
{name: "Jamie", age: 23, sex: "F"},
{name: "David", age: 25, sex: "M"},
{name: "Bob", age: 25, sex: "M"}
];
var oldestPeople = dataArray.reduce(function(max, cur) {
console.log("Max is " + max["name"]);
console.log("Cur is " + cur["name"]);
if (cur["age"] === max["age"]) {
return [max, cur];
} else if (cur["age"] > max["age"]) {
return cur;
} else {
return max;
}
});
I am able to get it to return two objects, but my max becomes undefined once [max, cur] is returned. Thanks again!

Looking at the documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
then the first callback it the return value from the previous invocation of the callback.
So the problem you are having is that sometimes you return and array [max,cut] and other times you return a single value cur or max -- just stick to always return an array and you should be fine, like
if (max)
console.log("Max is " + max[0]["name"]);
else
return [cur];
console.log("Cur is " + cur["name"]);
if (cur["age"] === max[0]["age"]) {
return max.concat([cur]);
} else if (cur["age"] > max[0]["age"]) {
return [cur].concat(max);
} else {
return max.concat([cur]);
}

If you want to use reduce, you could use something like
var oldestPeople = dataArray.reduce(function(max, cur) {
if (cur.age === max.age) {
max.people.push(cur);
} else if (cur.age > max.age) {
max.age = cur.age;
max.people = [cur];
}
return max;
}, {age: -Infinity, people: []}).people;
But maybe I would prefer a forEach:
var maxAge = -Infinity,
oldestPeople = [];
dataArray.forEach(function(cur) {
if (cur.age === maxAge) {
oldestPeople.push(cur);
} else if (cur.age > maxAge) {
maxAge = cur.age;
oldestPeople = [cur];
}
});

Related

Using array, How to print name of students who has highest marks in Javascript?

The code i tried
function findHighest(){
var highest = 0; // assum min 0
var highestItem;
$('tr').each(function(index, item){
if(index > 0){
var math = $(item).find('td').eq(1).text();
var eng = $(item).find('td').eq(2).text();
var lit = $(item).find('td').eq(3).text();
//alert(math)
var sum = parseFloat(math) + parseFloat(eng) + parseFloat(lit)
if (sum > highest){
highest = sum;
highestItem = item;
}
}
})
$(highestItem).css({ 'font-style': 'italic', 'color': 'red' });
}
I am trying to find name of student who got highest marks in class in at least two subjects in JavaScript?
const highestMarks=[];
const studentsWithHighestMarks=[];
const students = [{ name: "mini", subject: [{ maths : 20}, {english: 23}, { science: 25}, { sports: 24}] }, { name: "jerry", subject: [{ maths : 22}, {english: 20}, { science: 20}, { sports: 21}] }, { name: "john", subject: [{ maths : 23}, {english: 25}, { science: 20}, { sports: 21}] }];
students.forEach(student=>{
student.subject.forEach(subject=>{
for(let key in subject){
var index = highestMarks.findIndex(obj => {
return obj.subject === key
});
if (index===-1) {
highestMarks.push({
subject:key,
marks:subject[key],
students:[student.name]
})
}else if(highestMarks[index].marks<subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students=[student.name];
}
else if(highestMarks[index].marks==subject[key]){
highestMarks[index].marks=subject[key];
highestMarks[index].students.push(student.name);
}
}
})
});
students.forEach(student=>{
let count=0;
highestMarks.forEach(item=>{
if(item.students.includes(student.name)){
count++;
}
});
if(count>=2){
studentsWithHighestMarks.push(student.name)
}
})
console.log(studentsWithHighestMarks)
const subjectsConsidering = 2;
const getStudentMarks = (student) => {
const studentMarksList = [];
student.subject.forEach((subjectData) => {
studentMarksList.push(Object.values(subjectData)[0]);
});
const sum = studentMarksList.sort().reverse().reduce((sum, a, index) => {
// restrict only for first 2 subjects
if (index < subjectsConsidering) {
return sum + a;
}
return sum + 0;
});
return sum;
}
students.sort((studentA, studentB) => {
//return 0 for equal marks
return getStudentMarks(studentA) > getStudentMarks(studentB) ? -1 : 1;
});
console.log(students);
//This gives the sorted array of students having the highest marks in at least 2 subjects.
// Transform the data into a more manageable format
// { "subject": [["name", grade], ["name", grade], ["name", grade]] }
let transformed = students.reduce(
(data, student) => {
student.subject.forEach(subject => {
const key = keys(subject)[0];
const grade = [student.name, subject[key]];
if (!(key in data)) {
data[key] = [];
}
data[key].push(grade);
})
return data;
},
{}
)
// Utility function to compare grades
function gradeCompare(a, b) {
return a[1] > b[1] ? -1 : 1;
}
// List the top student in each subject
let names = Object.keys(transformed).map((subject) => {
return transformed[subject].sort(gradeCompare)[0][0];
});
// names :: [ "john", "john", "mini", "mini" ]
// Count the student names
let counts = names.reduce((acc, current) => {
acc[current] = (acc[current] || 0) + 1;
return acc;
}, {});
// counts :: { john: 2, mini: 2 }
// Find the maximum occurring count
let maxCount = Math.max(...Object.values(counts));
// maxCount :: 2
// Filter the keys that have that count
let topStudents = Object.keys(counts).filter(k => counts[k] === maxCount);
// topStudents :: [ "john", "mini" ]

Javascript : Add Key & Value at specific index in array of Object

I have array of Object like this.
let arr = [{name:"abc",age:26},{name:"xyz",age:23},{name:"pqr",age:10}]
let newVal = arr.map(function(el) {
if(el.age > 25){
var o = Object.assign({}, el);
o.gender = 'male';
return o;
}
})
console.log("New Val : " , newVal)
I would like to add {gender:'male'} to object where age is > 25
It says undefined to other objects.
Any help would be great.
Thank You.
You need to return the value if the object doesn't match the condition. Since you haven't retrned anything from from inside map if the condition is not fulfilled, you get undefined for the other objects
let arr = [{
name: "abc",
age: 26
}, {
name: "xyz",
age: 23
}, {
name: "pqr",
age: 10
}]
let newVal = arr.map(function(el) {
if (el.age > 25) {
var o = Object.assign({}, el);
o.gender = 'male';
return o;
}
return el; // return value here
})
console.log("New Val : ", newVal)
issue with your code is already solved in other answer by Shubham, ie when if clause is not executed you are not returning anything.
but i think forEach might be cleaner here
if you want to keep the original array you can copy it using copyArr = [...arr]
let arr = [{name:"abc",age:26},{name:"xyz",age:23},{name:"pqr",age:10}]
arr.forEach(function(el) {
if(el.age > 25)
el.gender = 'male';
})
console.log("New Val : " , arr)
It's missing the return statement when the condition is false.
You can do this in one line using an arrow function as follow:
let arr = [{name:"abc",age:26},{name:"xyz",age:23},{name:"pqr",age:10}],
newVal = arr.map((el) => Object.assign({}, el, el.age > 25 ? {gender: "male"} : {}));
console.log("New Val:", newVal);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You get a new array with map. Inside, you need to take either an copy of the object with a new property or the original object.
let array = [{ name: "abc", age: 26 }, { name: "xyz", age: 23 }, { name: "pqr", age: 10 }],
result = array.map(object => object.age > 25
? { ... object, gender: 'male' }
: object
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

how can I check the given keys age and remove them if <16

I need some help figuring out to have this fuction return only the people who are 16 and older.
function getNamesOfLegalDrivers(people) {
}
/* Do not modify code below this line */
const examplePeopleArray = [
{ name: 'John', age: 14 },
{ name: 'Joey', age: 16 },
{ name: 'Jane', age: 18 }
];
console.log(getNamesOfLegalDrivers(examplePeopleArray)) should be ["Joey", "Jane"]
Use filter function of Array interface.
result = people.filter((item) => item.age >= 16);
Use filter function to get the result
var result = examplePeopleArray.filter(x=> x.age >= 16);
This way you will get the filter value from the list.
Use map to get the desired output.
function getNamesOfLegalDrivers(people) {
return people.map(p => {
if(p.age >= 16){
return p.name;
}
}
}

Javascript: Finding largest value in object array and returning the key [duplicate]

This question already has answers here:
Get object from array by max property
(2 answers)
Closed 4 years ago.
I need to write a code that will look through the data array, and return the name of the oldest person.
console.log('The oldest person is ${oldestPerson}.')
let data = {
{
name: Henry,
age: 20,
job: 'store clerk'
},
{
name: Juliet,
age: 18,
job: 'student'
},
{
name: Luna,
age: 47,
job: 'CEO'
},
So far, I'm able to return separate arrays containing the names and ages, but I'm not sure how to find the oldest age and return name of the oldest person.
let names = data.map((person) => {
return person.name
});
let ages = data.map((person) => {
return Math.max(person.age)
});
Using reduce
let data = [{
name: ' Henry',
age: 20,
job: 'store clerk'
},
{
name: 'Juliet',
age: 18,
job: 'student'
},
{
name: 'Luna',
age: 47,
job: 'CEO'
}
];
var max = 0;
console.log(data.reduce((acc, a) => {
if (a.age > max) {
acc = a.name
max = a.age;
}
return acc;
}, ""))
To get the max age, you've got no choice but to loop over the entire array (and get the oldest one). So while you're looping over the array, grab the name too.
This is one approach of many:
let highestAge = 0;
const oldestName = data.reduce((prev,curr) => {
if(curr.age > highestAgo) {
highestAge = curr.age;
return curr.name;
}
return prev;
},'');

how can I trans this {'person': {'name': 'cc', 'age': 12} } to {'person.name': 'cc', 'person.age': 12}?

like this, I have a object:
{
'person': {
'like': {
'color': 'red',
'food': 'rice'
},
'name': {
'first': {
'word': 'bob',
'num': 4
}
},
'age': {
'next': 18,
'now': 19
}
}
}
I want to trans it to this:
{
'person.like.color': 'red',
'person.like.food': 'rice',
'name.first.word': 'bob',
'name.first.num':4,
....
}
how can I trans it?
this is three nest, If I have five nest or more? how can I do this?
An array like the one you want can't happen, but you can get a similar object with this:
var newObj = {};
var temp = {};
for (var a in p) {
if (p.hasOwnProperty(a)) {
temp = p[a];
for (var b in p[a]) {
if (p[a].hasOwnProperty(b)) {
newObj[a + "." + b] = temp[b];
}
}
}
}
Check the output:
http://jsbin.com/cutudovala/edit?js,console
This solution will flatten a nested object any number of levels deep, containing objects or plain values.
function flatten_to_dots(o) {
var result = {};
function _flatten(o, prefix) {
Object.keys(o).forEach(function(k) {
var value = o[k];
if (value && typeof value === 'object') _flatten(value, prefix + k + '.');
else result[prefix + k] = value;
});
}
_flatten(o, '');
return result;
}
The internal function _flatten loops over the keys of an object. If the corresponding value is a scalar, it is simply placed in the result. If it is an object, we call _flatten recursively to process its properties, passing along the prefix we want to use for its keys.
> flatten_to_dots({'person': {'name': 'cc', 'age': 12 }})
< {person.name: "cc", person.age: 12}
> flatten_to_dots({person: { name: {first: 'Joe', last: 'Blow'}, age: 12}})
< {person.name.first: "Joe", person.name.last: "Blow", person.age: 12}

Categories