How to filter array of objects by property? for example in this array if two or more objects have same properties like name and lastname I want to remove either of them and leave only unique one in an array. example arr:
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
result should be either
[ {name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
or
[ {name: "George", lastname: "GeorgeLast", age: 12},
{name: "Bob", lastname: "GeorgeLast", age: 12}]
Apply the technique shown in this answer, which is:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
...but using findIndex with some criteria rather than just indexOf.
let people = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
]
let result = people.filter(
(person, index) => index === people.findIndex(
other => person.name === other.name
&& person.lastname === other.lastname
));
console.log(result);
As for whether it keeps 12-year-old George or 13-year-old George, it is a matter of how findIndex works, which so happens to return the first matching element. So in your example case it will keep 12-year-old George.
The Map object holds key-value pairs and remembers the original insertion order of the keys.
const arr = [
{ name: "George", lastname: "GeorgeLast", age: 12 },
{ name: "George", lastname: "GeorgeLast", age: 13 },
{ name: "Bob", lastname: "GeorgeLast", age: 12 }
];
const newMap = new Map();
arr.forEach((item) => newMap.set(item.name, item));
console.log([...newMap.values()]);
Another solution.
Here you don't need to iterate through the list n*n/2 times (if I count correctly).
On the other hand, this one looks less concise and uses more memory.
Use whichever you prefer.
const arr = [
{name: "George", lastname: "GeorgeLast", age: 12},
{name: "George", lastname: "GeorgeLast", age: 13},
{name: "Bob", lastname: "GeorgeLast", age: 12}
];
const obj = {}
arr.forEach(v => {
if (!obj[v.name]) {
obj[v.name] = {}
}
if (!obj[v.name][v.lastname]) {
obj[v.name][v.lastname] = v;
}
})
const result = [];
Object.values(obj).forEach(nameObj =>
Object.values(nameObj).forEach(surnObj => result.push(surnObj))
);
console.log(result)
Using javascript, I have this array:
people = [{name: carlo, lastname: Garcia, age: 28},
{name: maria, lastname: pia, age: 20},
{name: elly, lastname: martinez, age: 25}]
I would like to transform it into:
arrayList = [{data: {name: carlo, lastname: garcia, age: 28}, checked: false},
{data: {name: carlo, lastname: garcia, age: 28}, checked: false},
{data: {name: carlo, lastname: garcia, age: 28}, checked: false}]
How can I do it?
You want to use Array.prototype.map
var people = [{ name: "carlo", lastname: "Garcia", age: 28 }, { name: "maria", lastname: "pia", age: 20 }, { name: "elly", lastname: "martinez", age: 25 }]
var arrayList = people.map(person => ({
data: person,
checked: false,
}))
console.log(arrayList);
Just use map(). Return an object with data and checked fields.
Where:
data is set to each person
checked is set to false
people = [{name: 'carlo', lastname: 'Garcia', age: 28},{name: 'maria', lastname: 'pia', age: 20},{name: 'elly', lastname: 'martinez', age: 25}]
arrayList = people.map(p => ({ data: p, checked: false }))
console.log(arrayList)
Say you have csv data file like this:
name, age
Bob, 27
George, 25
Bill, 22
Henry,27
Carol,25
Mary, 28
Harold,27
Jane, 25
I want to aggregate totals by age for a bar chart. So that I get totals like this: age 27(3), age 25(2), etc.
I am using d3 v4
As mentioned in the comments, you could use d3.nest:
const data = [
{name: 'Bob', age: 27},
{name: 'George', age: 25},
{name: 'Bill', age: 2},
{name: 'Henry', age: 27},
{name: 'Carol', age: 25},
{name: 'Mary', age: 28},
{name: 'Harold', age: 27},
{name: 'Jane', age: 25},
];
console.log(d3.nest()
.key(d => d.age)
.rollup(results => results.length)
.entries(data));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
how can I reduce an array of objects of this type:
[
{id: 1, name: 'jhon', lastname: 'doe', age: 30},
{id: 2, name: 'max', lastname: 'wall', age: 20},
{id: 3, name: 'fer', lastname: 'baneg', age: 15}
]
I need to get a new array just with these values:
[
{id: 1, name: 'jhon'},
{id: 2, name: 'max'},
{id: 3, name: 'fer'}
]
You can use map() method for this with ES6 parameter destructuring.
const data = [{id: 1, name: 'jhon', lastname: 'doe', age: 30},{id: 2, name: 'max', lastname: 'wall', age: 20},{id: 3, name: 'fer', lastname: 'baneg', age: 15}]
const result = data.map(({id, name}) => ({id, name}))
console.log(result)
I have an object with sales numbers and want to get return the name and sales of the highest seller, but I keep getting an error of cannot read property of undefined:
var salesTeam = [{name: {first: 'aleen', last: 'atkins'}, age: 26, sales: '$2314'},
{name: {first: 'alvaro', last: 'angelos'}, age: 55, sales: '$1668'},
{name: {first: 'denese', last: 'dossett'}, age: 29, sales: '$9248'},
{name: {first: 'douglas', last: 'denney'}, age: 53, sales: '$5058'},
{name: {first: 'earline', last: 'erickson'}, age: 19, sales: '$18876'},
{name: {first: 'herman', last: 'hazell'}, age: 25, sales: '$2746'},
{name: {first: 'homer', last: 'hirth'}, age: 26, sales: '$474'},
{name: {first: 'hwa', last: 'heidt'}, age: 53, sales: '$9607'},
{name: {first: 'hyon', last: 'hampshire'}, age: 46, sales: '$13598'},
{name: {first: 'issac', last: 'ingerson'}, age: 45, sales: '$5225'},
{name: {first: 'jeraldine', last: 'joplin'}, age: 39, sales: '$2891'},
{name: {first: 'jin', last: 'jeffrey'}, age: 17, sales: '$14402'},
{name: {first: 'joleen', last: 'jolin'}, age: 45, sales: '$15736'},
{name: {first: 'jude', last: 'jarrett'}, age: 53, sales: '$7557'},
{name: {first: 'magda', last: 'mireles'}, age: 18, sales: '$1498'},
{name: {first: 'mistie', last: 'montealegre'}, age: 31, sales: '$6920'},
{name: {first: 'nancy', last: 'napoli'}, age: 49, sales: '$5255'},
{name: {first: 'regine', last: 'rohrbaugh'}, age: 33, sales: '$7881'},
{name: {first: 'rolando', last: 'riebel'}, age: 35, sales: '$8573'},
{name: {first: 'scarlett', last: 'stagg'}, age: 36, sales: '$7126'},
{name: {first: 'sherron', last: 'strawn'}, age: 36, sales: '$8848'},
{name: {first: 'susan', last: 'shilling'}, age: 29, sales: '$8542'},
{name: {first: 'tama', last: 'tworek'}, age: 16, sales: '$9200'},
{name: {first: 'tonisha', last: 'taunton'}, age: 41, sales: '$5219'},
{name: {first: 'vergie', last: 'villescas'}, age: 25, sales: '$8712'}];
var highestEarner = function (companies) {
var ret = companies.reduce(function(acc,element,i){
if (parseInt(element['sales'].slice(1)) > acc['sales']){
acc['sales'] = element['sales'];
acc['name'] = element['name']['first'] +" "+ element['name']['last'];
}
},{sales: 0, name: ''});
return ret;
};
console.log(highestEarner(salesTeam));
You need to return the accumulator in each iteration, ie you are missing return acc after the if {...}. Also, you're assigning the currency-formatted value to acc['sales'] so you'll need to slice and parseInt that too (or just store the numeric value)...
const salesTeam = [{"name":{"first":"aleen","last":"atkins"},"age":26,"sales":"$2314"},{"name":{"first":"alvaro","last":"angelos"},"age":55,"sales":"$1668"},{"name":{"first":"denese","last":"dossett"},"age":29,"sales":"$9248"},{"name":{"first":"douglas","last":"denney"},"age":53,"sales":"$5058"},{"name":{"first":"earline","last":"erickson"},"age":19,"sales":"$18876"},{"name":{"first":"herman","last":"hazell"},"age":25,"sales":"$2746"},{"name":{"first":"homer","last":"hirth"},"age":26,"sales":"$474"},{"name":{"first":"hwa","last":"heidt"},"age":53,"sales":"$9607"},{"name":{"first":"hyon","last":"hampshire"},"age":46,"sales":"$13598"},{"name":{"first":"issac","last":"ingerson"},"age":45,"sales":"$5225"},{"name":{"first":"jeraldine","last":"joplin"},"age":39,"sales":"$2891"},{"name":{"first":"jin","last":"jeffrey"},"age":17,"sales":"$14402"},{"name":{"first":"joleen","last":"jolin"},"age":45,"sales":"$15736"},{"name":{"first":"jude","last":"jarrett"},"age":53,"sales":"$7557"},{"name":{"first":"magda","last":"mireles"},"age":18,"sales":"$1498"},{"name":{"first":"mistie","last":"montealegre"},"age":31,"sales":"$6920"},{"name":{"first":"nancy","last":"napoli"},"age":49,"sales":"$5255"},{"name":{"first":"regine","last":"rohrbaugh"},"age":33,"sales":"$7881"},{"name":{"first":"rolando","last":"riebel"},"age":35,"sales":"$8573"},{"name":{"first":"scarlett","last":"stagg"},"age":36,"sales":"$7126"},{"name":{"first":"sherron","last":"strawn"},"age":36,"sales":"$8848"},{"name":{"first":"susan","last":"shilling"},"age":29,"sales":"$8542"},{"name":{"first":"tama","last":"tworek"},"age":16,"sales":"$9200"},{"name":{"first":"tonisha","last":"taunton"},"age":41,"sales":"$5219"},{"name":{"first":"vergie","last":"villescas"},"age":25,"sales":"$8712"}];
var highestEarner = function (companies) {
var ret = companies.reduce(function(acc,element) {
let currentSales = parseInt(element.sales.slice(1))
if (currentSales > acc.sales) {
acc.sales = currentSales;
acc.name = `${element.name.first} ${element.name.last}`
}
return acc;
},{sales: 0, name: ''});
return ret;
};
console.log(highestEarner(salesTeam));
The simple rule while working with reducer is that, whatever data format you have in each element of the array, make sure you are returning the same format including all the elements in every run so that it can use the returned value as accumulator (acc) for the next run.
A simple mistake which I learned from below:
This fixed the issue.