I have a users list which have firstname and age. I want to filter out the users which have same age. Age will not be known , it will come dynamically , so cannot do filter(age > 26)
const users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'RohanB', age: 26},
]
Use reduce() we can group user have the same age together,then use filter() we can get users have the same age
const users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'RohanB', age: 26},
]
let result = users.reduce((a,v) => {
let obj = a.find(i => i.age == v.age)
if(obj){
obj.firstName.push(v.firstName)
}else{
a.push({'firstName':[v.firstName],'age':v.age})
}
return a
},[]).filter(u => u.firstName.length > 1)
console.log(result)
First, reduce them to dict containing arrays of same age. Then go forEach key in dict and return only those that are single.
const users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'RohanB', age: 26},
]
var groupByRemoveMultiple = function(xs, key) {
let gb = xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
let res = [];
Object.keys(gb).forEach(function(key, index) {
if (gb[key].length === 1) {
res.push(gb[key]);
}
});
return res;
};
arr = groupByRemoveMultiple(users, 'age');
console.log(arr);
Your question is not clear but this should return users with age dynamically
const users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'RohanB', age: 26},
]
function filterAge(arr, uAge) {
const newArray = [];
for(let i = 0; i < arr.length; i++)
{
let userAge = arr[i].age;
if(userAge === uAge)
{
newArray.push(arr[i]);
}
}
return newArray;
}
// const result = filterAge(users, dynamicAge); // dynamicAge should be the variable of the age
const result = filterAge(users, 23);
console.log(result);
The solution will be to group your Array elements by age property.
This is a way for using reduce JS function in order to group items by specific object property:
const users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'Ronne', age: 23},
{firstName: 'RohanB', age: 26},
];
console.log("users before grouping: ", users);
const usersGrouped = users.reduce((group, user) => {
const { age } = user;
group[age] = group[age] ?? [];
group[age].push(user);
return group;
}, {});
console.log("users grouped: ", usersGrouped);
Then you can use output as you want.
How about this?
let users = [
{firstName: 'Rohan', age: 26},
{firstName: 'Ronny', age: 22},
{firstName: 'Ronnie', age: 23},
{firstName: 'RohanB', age: 26},
{firstName: 'RohanC', age: 26},
{firstName: 'RohanD', age: 22},
{firstName: 'RohanE', age: 23},
{firstName: 'RohanF', age: 24},
{firstName: 'RohanG', age: 25}
]
const dic = users.map(a => a["age"])
.reduce((c, el)=>{c[el] = (c[el]||0)+1; return c}, {});
console.log(dic);
Object.keys(dic).forEach((k) => {
if(dic[k] !== 1){
users = users.filter(a => a["age"] != k);
}
});
console.log(users);
Related
I have a list of objects:
[{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
I need a simple way to filter out duplicates with regard to the name property, so:
[{name: "bob", age: "14"}, {name: "sue", age: "21"}]
There seem to be quite a few array duplicate removal questions, but not any based on a property. It can ignore all other fields.
Iterate the array, place all name values in a hash and skip objects whose name is already in the hash:
filterBy = function(ary, prop) {
var seen = {};
return ary.filter(function(item) {
var key = item[prop];
if(seen[key] === 1)
return false;
seen[key] = 1;
return true;
});
}
//
a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
b = filterBy(a, 'name');
console.log(b);
ES6 version:
filterBy = function(ary, prop) {
var seen = new Set();
return ary.filter(item => !seen.has(item[prop]) && seen.add(item[prop]));
}
a = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}]
b = filterBy(a, 'name');
console.log(b);
You can do it with 2 for loops as follows. All you have to do is, keeping a result array and every time you insert into it, check whether the name attributes are equal.
function findDuplicate(){
var array= [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];
var result=[];
for(x in array){
var found=false;
for(y in result){
if(result[y].name.localeCompare(array[x].name)==0){
found=true;
}
}
if(!found){
result.push(array[x]);
}
}
console.log(result);
}
You could do this with forEach and thisArg param.
var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}];
var result = [];
data.forEach(function(e) {
if (!this[e.name]) {
this[e.name] = e;
result.push(this[e.name]);
}
}, {});
console.log(result)
Or with forEach and map()
var data = [{name: "bob", age: "14"}, {name: "bob", age: "16"}, {name: "sue", age: "21"}], result =[];
data.forEach(function(e) {
if(result.map(a => {return a.name}).indexOf(e.name) == -1 ) result.push(e);
});
console.log(result)
You could use Array#filter and a this object for marking, if the same name is already filtered.
var array = [{ name: "bob", age: "14" }, { name: "bob", age: "16" }, { name: "sue", age: "21" }],
filtered = array.filter(function (a) {
if (!this[a.name]) {
this[a.name] = true;
return true;
}
}, Object.create(null));
console.log(filtered);
For the straightforward comparison in the Q., there are some
good answers here. If you want to provide a custom comparison
function that will work on e.g. object values, or that uses
a RegExp, then take a look at the following.
var dedupwhen = function(fn, list){
if(list[0] === undefined){
return [];
}
// Join the first item to the remainder that has had the first
// item filtered out (according to fn) and then been
// deduplicated itself.
return [list[0]].concat(dedupwhen(fn, list.slice(1).filter(function(item){
return !fn(list[0], item);
})));
};
var similarname = function(x,y){
return RegExp('^' + x.name + '$', 'i').test(y.name);
};
var list = [
{name: 'Sue', age: 44},
{name: 'Bob', age: "14"},
{name: 'bob', age: "16"},
{name: 'sue', age: "21"}
];
console.log(dedupwhen(similarname, list));
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)
I have an array which has docs like this
[{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}]
how can i find all people who for example are less or equal then 30 ?
You can use filter()
const arr = [{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}];
const res = arr.filter(x => x.age <=30)
console.log(res)
If you want the names of the persons only then use map() after filter()
const arr = [{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}];
const res = arr.filter(x => x.age <=30).map(x => x.name)
console.log(res)
Use Object.entries to key a nested with index of element [index,value] then use filter() on that and at the end map() to get only index
const arr = [{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}];
const res = Object.entries(arr).filter(([_,v]) => v.age <=30).map(x => +x[0])
console.log(res)
Use Array.filter
let arr =[{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}];
let result = arr.filter(v => v.age <= 30);
console.log(result);
Yeh filter it is - and with some exagaration in readability:
const dox = [{name: "Tom", age: 20}, {name: "Frank", age: 25}, {name: "Susie", age: 29}, {name: "Tina", age: 32}]
const arrayWithPeopleWhoForExampleAreLessOrEqualThen30 =
dox.filter(peopleWhoForExampleAreLessOrEqualThen30)
function peopleWhoForExampleAreLessOrEqualThen30(doc){
return doc.age <= 30
}
I have 2 arrays of objects
var arr1 = [{id: "145", firstname: "dave", lastname: "jones"},
{id: "135", firstname: "mike",lastname: "williams"},
{id: "148", firstname: "bob",lastname: "michaels"}];
var arr2 = [{id: "146", firstname: "dave", lastname: "jones"},
{id: "135", firstname: "mike", lastname: "williams"},
{id: "148", firstname: "bob", lastname: "michaels"}];
I want to find the objects where the id exists in only one of the arrays and either log the object to the console or push the object to a new array.
Therefore I want to end up with
var arr1 = [{id: "145", firstname: "dave", lastname: "jones"}]
var arr2 = [{id: "146", firstname: "dave", lastname: "jones"}]
I tried using a forEach loop and splicing matching id's out of the array
arr1.forEach(function(element1, index1) {
let arr1Id = element1.id;
arr2.forEach(function(element2, index2) {
if (arr1Id === element2.id) {
arr1.splice(element1, index1)
arr2.splice(element2, index2)
};
});
});
console.log(arr1);
console.log(arr2);
But I ended up with
arr1
[ { id: '135', firstname: 'mike', lastname: 'williams' },
{ id: '148', firstname: 'bob', lastname: 'michaels' } ]
arr2
[ { id: '135', firstname: 'mike', lastname: 'williams' },
{ id: '148', firstname: 'bob', lastname: 'michaels' } ]
You could take a Set for every array's id and filter the other array by checking the existence.
var array1 = [{ id: "145", firstname: "dave", lastname: "jones" }, { id: "135", firstname: "mike", lastname: "williams" }, { id: "148", firstname: "bob", lastname: "michaels" }],
array2 = [{ id: "146", firstname: "dave", lastname: "jones" }, { id: "135", firstname: "mike", lastname: "williams" }, { id: "148", firstname: "bob", lastname: "michaels" }],
set1 = new Set(array1.map(({ id }) => id)),
set2 = new Set(array2.map(({ id }) => id)),
result1 = array1.filter(({ id }) => !set2.has(id)),
result2 = array2.filter(({ id }) => !set1.has(id));
console.log(result1);
console.log(result2);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Just use !arr.some() inside a Array.prototype.filter():
const arr1 = [{id: "145", firstname: "dave", lastname: "jones"},{id: "135", firstname: "mike",lastname: "williams"},{id: "148", firstname: "bob",lastname: "michaels"}],
arr2 = [{id: "146", firstname: "dave", lastname: "jones"},{id: "135", firstname: "mike", lastname: "williams"},{id: "148", firstname: "bob", lastname: "michaels"}],
newArr1 = arr1.filter(x => !arr2.some(y => y.id === x.id)),
newArr2 = arr2.filter(x => !arr1.some(y => y.id === x.id));
console.log(newArr1, newArr2);
Hello please try using combination of filter and findindex like the below snippet and let me know.
var arr1 = [{id: "145", firstname: "dave", lastname: "jones"},
{id: "135", firstname: "mike",lastname: "williams"},
{id: "148", firstname: "bob",lastname: "michaels"}];
var arr2 = [{id: "146", firstname: "dave", lastname: "jones"},
{id: "135", firstname: "mike", lastname: "williams"},
{id: "148", firstname: "bob", lastname: "michaels"}];
let unmatchedArr1 = arr1.filter(element => {
let targetIndex = arr2.findIndex(e => element.id === e.id);
return targetIndex >= 0 ? false : true;
})
let unmatchedArr2 = arr2.filter(element => {
let targetIndex = arr1.findIndex(e => element.id === e.id);
return targetIndex >= 0 ? false : true;
})
console.log(unmatchedArr1);
console.log(unmatchedArr2);