From array of Object , get array of only matched key value - javascript

Suppose I have an array of object:
var students = [{name: 'Nick',achievements: 158,points: 1473}, {name: 'Nick',achievements: '175',points: '16375'},
{name: 'Ramon',achievements: '55',points: '2025'}];
I want to extract points from name Nick only in an array.
Like if (name=='Nick), O/P should be [1473,16375]
I tried:
var arrayPoints = students.map(function (el) {
if(el.name=='Nick'){
return el.points
}
});
But it gives me o/p:
console.log(arrayPoints)
[1473,16375,undefined] o/p

A look to the methods:
Array#map returns a (new) value for each element.
Array#filter returns exactly the element if the return value of the callback is truthy
You could take two steps, one for filtering the items and another to get the values from.
const
students = [{ name: 'Nick', achievements: 158, points: 1473 }, { name: 'Nick', achievements: '175', points: '16375' }, { name: 'Ramon', achievements: '55', points: '2025' }],
arrayPoints = students
.filter(student => student.name === 'Nick')
.map(student => student.points);
console.log(arrayPoints);
If Array#flatMap is implemented, you could take a single loop and filter and return a value.
The empty array has no items and this array is a neutral value which does not turn up in the result array.
const
students = [{ name: 'Nick', achievements: 158, points: 1473 }, { name: 'Nick', achievements: '175', points: '16375' }, { name: 'Ramon', achievements: '55', points: '2025' }],
arrayPoints = students
.flatMap(student => student.name === 'Nick'
? student.points
: []
);
console.log(arrayPoints);

For single loop result without undefined. You could do with Array#reduce
students.reduce(function (acc,el) {
if(el.name=='Nick'){
acc.push(el.points)
}
return acc
},[]);

You can use reduce for that:
The reduce() method executes a reducer function (that you provide) on each element of the array, resulting in single output value.
So You can use it and check if the name is indeed Nick (el is the currentValue).
if so then push the points to the accumulator (which is arr).
[] represent the initialValue passed to the reduce function.
var arrayPoints = students.reduce((arr, el) =>
(el.name === 'Nick' && arr.push(el.points), arr), [])
You can find more info regarding reduce here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

Related

How to insert object via push method in javascript?

I cannot add an object via push method to javascript, my code is:
arrObj = [
{
name: "Krunal",
age: 26,
},
{
name: "Ankit",
age: 24,
},
];
function onAdd() {
return CART.push(arrObj);
}
What is the reason ?
if CART is an array, you should use .concat() instead
const newArray = CART.concat(arrObj)
as arr1.concat(arr2) will concat two arrays and return the result
whereas arr1.push(arr2) will result in an array within an array

How can i find out the last entered object in an array of objects, where similar objects can be entered multiple times

Suppose,
i have an object with properties, details : {"name","id"} , now there is an array that holds collection of details. now suppose , an object with {name:max, id:55} is pushed in the array more than once. how do i find out the last entered {name:max,id:55} from that array using TypeScript .
You can do it with pure JavaScript and lastIndexOf:
const myArray = [{
name: "max",
id: 55
}, {
name: "john",
id: 13
}, {
name: "susan",
id: "123"
}, {
name: "max",
id: 55
}];
const lastEntered = (name, id) => {
var matches = myArray.filter(e => e.name == name && e.id == id);
return matches.length - 1;
}
console.log(lastEntered("max", 55));
Array is last in first out data structure.
So the last in element will occupy the element with the largest index.
So you may get the element by array[array.length-1]
You can use reduce to change the array to an object, where the key is a value from the object, and the value is the last index of that key.
const details = [{ name: 'max', id: 55 }];
const detailsMap = details.reduce((acc, person, index) => {
acc[person.id] = index;
return acc;
}, {});
const lastIndexOfMax = detailsMap[55];
Here we set the id from the detail object to the key (because I assumed that each id is unique). When we enter that key into the details map, it returns to use the index of the array where that id is last located.

How do I transform an array to hold data based on a value in the data?

I have seen some questions that might look similar but none is the solution in my case. I want to regroup and recreate my array the way that it is arranged or grouped based on one of my values(age). I want to have all data of the same "age" in one place. So here is my sample array:
[
{
"age": 15,
"person": {
name: 'John',
hobby: 'ski'
},
},
{
"age": 23,
"person": {
name: 'Suzi',
hobby: 'golf'
},
},
{
"age": 23,
"person": {
name: 'Joe',
hobby: 'books'
}
},{
"age": 25,
"person": {
name: 'Rosi',
hobby: 'books'
}
},{
"age": 15,
"person": {
name: 'Gary',
hobby: 'books'
}
},
{
"age": 23,
"person": {
name: 'Kane',
hobby: 'books'
}
}
]
And I need to have an array that kind of have age as a key and person as value, so each key could have multiple values meaning the value will kind of be an array itself.
I have read this and this questions and many more but they were not exactly the same.
I feel like I need to use reduce to count duplicate ages and then filter it based on that but how do I get the values of those ages?
EIDT:
Sorry for not being clear:
This is what I need:
{
23: [
{ name: 'Suzi', hoby: 'golf' },
{ name: 'Joe', hobby: 'books'}
],
15: [
{ name: 'Gary', hobby: 'books' }
] ,
.
.
.
}
You're actually going to want to reduce, not filter. Filtering an Array means to remove elements and place the kept elements into a new container. Reducing an array means to transform it into a single value in a new container. Mapping an array means to transform every value in place to a new container. Since you want to change how the data is represented that's a Reduction, from one form to another more condensed form.
Assume your Array of values is stored in let people = [...]
let peopleByAge = people.reduce(function (accumulator, value, index, array){
// The first time through accumulator is the passed extra Object after this function
// See the MDN for Array.prototype.reduce() for more information
if (accumulator[value.age] == undefined){
accumulator[value.age] = [];
}
accumulator[value.age].push(value);
return accumulator
}, {})
console.log(peopleByAge) // { 23: [{ age: 23, name: ..., hobby: ...}, ...], 13: [...], ...}
You can find the MDN article for Array#reduce() here
Thanks to #RobertMennell who patiently answered me and I voted as answer. But I just wanted to write my version which MDN had a great example of. It is a longer version assuming the people is the array name:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
if (!acc[key]) {
acc[key] = [];
}
acc[key].push(obj);
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));
Update:
More polished using ternary operator:
const groupedByvalue = 'age';
const groupedArray = people;
const groupBy = (peopleArray, value) => {
return peopleArray.reduce((acc, obj) => {
const key = obj[value];
(!acc[key]) ? (acc[key] = []) : (acc[key].push(obj))
return acc;
}, {});
}
console.log(groupBy(groupedArray,groupedByvalue));

Angular 4 GroupBy Array Data

I have an array which looks like:
var data = [
{
student: "sam",
English: 80,
Std: 8
},
{
student: "sam",
Maths: 80,
Std: 8
},
{
student: "john",
English: 80,
Std: 8
},
{
student: "john",
Maths: 80,
Std: 8
}
];
and I need to get the total marks irrespective of subject for student sam.
By filtering data array by student name and then looping the filtered data, can get the individual student total marks.
Is there any groupBy function as similar to SQL in Typescript.
This seems like it can be done with a simple reduce method on the array. Reduce will iterate over an array and pass each item into the provided predicate function. Each iteration should return the accumulator obj/array/val.
I wasn't sure what you wanted the data structure to be, but you can control the structure by the inner working of the function you pass to reduce.
studentScores = this.data.reduce((accumulator, item) => {
const key = Object.keys(item)
.filter(k => k !== 'student')
.filter(k => k !== 'Std')[0];
const prevValue = accumulator[item.student] || 0;
const studentName = item.student;
accumulator[studentName] = prevValue + item[key];
return accumulator;
}, {});
I posted a working example in a stackblitz at https://stackblitz.com/edit/angular-xcjzzf
You have to do it using dictionary. Easy way to grouping is used a map.there mark's name is changing so the task is difficult.This is stackblitz link.

ES6 filter - how to return an object instead of an array?

I have bunch of array of object, I want to get particular object using filter, but I got array using below code.
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}]
const x = target.filter(o => o.id === 1)
console.log(x)
As said in the comments, filter won't allow you to get a particular object from an array - it just returns another array which elements satisfy the given predicate. What you actually need is Array.prototype.find(). Quoting the doc:
The find() method returns the value of the first element in the array
that satisfies the provided testing function. Otherwise undefined is
returned.
So your code looks like this:
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}];
const x = target.find(o => o.id === 1);
console.log(x); // {name: "abc", id: 1}
array.filter always return array. But you can try this-
const target = [{
name: 'abc',
id: 1
}, {
name: 'def',
id: 2
}]
let obj = {}
const x = target.filter( (o, index) => {
if(o.id === 1)
obj = target[index]
})
console.log(obj)
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
Array.prototype.filter will return array containing elements from original array that passed test function.
If you are sure that id's are unique simply do x[0] to get result.
It's very easy just get first item in retrned as:
const target = [{name: 'abc', id: 1}, {name: 'def', id: 2}]
const x = target.filter(o => o.id === 1)
console.log(x[0])

Categories

Resources