Coding Meetup #9 - Higher-Order Functions Series - Is the meetup age-diverse? - javascript

I am currently trying to complete Coding Meetup #9 on CodeWars.
How can I complete this only using for loops and if/else statements?
Here is the CodeWars Kata question:
You will be given an array of objects (associative arrays in PHP)
representing data about developers who have signed up to attend the
next coding meetup that you are organising.
Your task is to return: true if developers from all of the following
age groups have signed up: teens, twenties, thirties, forties,
fifties, sixties, seventies, eighties, nineties, centenarian (at least
100 years young). false otherwise.
For example, given the following input array:
var list = [
{ firstName: 'Harry', lastName: 'K.', country: 'Brazil', continent: 'Americas', age: 19, language: 'Python' },
{ firstName: 'Kseniya', lastName: 'T.', country: 'Belarus', continent: 'Europe', age: 29, language: 'JavaScript' },
{ firstName: 'Jing', lastName: 'X.', country: 'China', continent: 'Asia', age: 39, language: 'Ruby' },
{ firstName: 'Noa', lastName: 'A.', country: 'Israel', continent: 'Asia', age: 40, language: 'Ruby' },
{ firstName: 'Andrei', lastName: 'E.', country: 'Romania', continent: 'Europe', age: 59, language: 'C' },
{ firstName: 'Maria', lastName: 'S.', country: 'Peru', continent: 'Americas', age: 60, language: 'C' },
{ firstName: 'Lukas', lastName: 'X.', country: 'Croatia', continent: 'Europe', age: 75, language: 'Python' },
{ firstName: 'Chloe', lastName: 'K.', country: 'Guernsey', continent: 'Europe', age: 88, language: 'Ruby' },
{ firstName: 'Viktoria', lastName: 'W.', country: 'Bulgaria', continent: 'Europe', age: 98, language: 'PHP' },
{ firstName: 'Piotr', lastName: 'B.', country: 'Poland', continent: 'Europe', age: 128, language: 'JavaScript' }
];
Your function should return true as there is at least one developer
from each age group
Here is my code:
function isAgeDiverse(list) {
for (let i = 0; i < list.length; i++) {
if (list[i].age >= 18) {
return false;
}
}
return true;
}

Naive but working approach:
function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}
function isAgeDiverse(list) {
requiredAgeGroups = [1, 2, 3, 4, 5, 6, 7, 8, 9]
availableAgeGroups = [];
list.forEach(el => {
availableAgeGroups.push(Math.floor(el.age / 10));
});
availableAgeGroups = availableAgeGroups.filter(onlyUnique);
for (let i = 1; i < 10; i++ ){
if (availableAgeGroups.indexOf(i) == -1){
return false;
}
}
availableAgeGroups = availableAgeGroups.filter((i) => i > 9);
return availableAgeGroups.length > 0;
}

Related

Languages Statistic

I have to implement the "getLanguagesStatistic" function, which will help the IT magazine summarize 2019 in terms of the popularity of programming languages.
As input, the function receives an array of user reviews. You need to return an object in the format {languageName: count, anotherLanguageName: anotherCount, ...}, where languageName is the name of the language in the string, and count is the number of reviews left by programmers using this language.
In this case, only those user reviews that were left in 2019 should be taken into account. The revocation year is stored in the year field, the language in the language field.
Feedback is provided in the following format:
{ firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'C', year: 2019 }
Input data:
const data = [
{ firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'C', year: 2019 },
{ firstName: 'Anna', lastName: 'R.', country: 'Liechtenstein', continent: 'Europe', age: 52, language: 'JavaScript', year: 2019 },
{ firstName: 'Piter', lastName: 'G.', country: 'Sweden', continent: 'Europe', age: 30, language: 'JavaScript', year: 2019 },
{ firstName: 'Ramon', lastName: 'R.', country: 'Paraguay', continent: 'Americas', age: 29, language: 'Ruby', year: 2014 },
{ firstName: 'George', lastName: 'B.', country: 'England', continent: 'Europe', age: 81, language: 'C', year: 2016 },
];
const result = getLanguagesStatistic(data);
Output data:
console.log(result);
// {
// C: 1,
// JavaScript: 2
// }
Function:
const getLanguagesStatistic = (feedbacks) => {
//code here
};
I just managed to make the filter of the year. I tried the rest of the functionality through reduce, destructuring, but it doesn’t work, so I only write what I did.
Do I really need to use destructuring here?
My try:
const getLanguagesStatistic = (feedbacks) => {
return feedbacks.filter( (f) => f.year == 2019)
};
Something like this
const getLanguagesStatistic = (feedbacks) => {
return feedbacks.reduce((acc, {language, year}) => {
if (year === 2019) {
acc[language] = (acc[language]||0) + 1;
}
return acc;
}, {});
};
const data = [
{ firstName: 'Noah', lastName: 'M.', country: 'Switzerland', continent: 'Europe', age: 19, language: 'C', year: 2019 },
{ firstName: 'Anna', lastName: 'R.', country: 'Liechtenstein', continent: 'Europe', age: 52, language: 'JavaScript', year: 2019 },
{ firstName: 'Piter', lastName: 'G.', country: 'Sweden', continent: 'Europe', age: 30, language: 'JavaScript', year: 2019 },
{ firstName: 'Ramon', lastName: 'R.', country: 'Paraguay', continent: 'Americas', age: 29, language: 'Ruby', year: 2014 },
{ firstName: 'George', lastName: 'B.', country: 'England', continent: 'Europe', age: 81, language: 'C', year: 2016 },
];
const result = getLanguagesStatistic(data);
console.log(result);

Filter an array of objects by a highest value (including highest matching values)

I don't know why this doesn't work...
function findOldest(list) {
let oldest = Math.max.apply(null, list.map(function(dev) { return
dev.age; }));
return list.filter((dev, age) => dev[age].includes(oldest));
}
I need to return only the oldest person or persons (if the oldest age matches).
This is an example array:
[
{ firstName: 'Gabriel', country: 'Monaco', age: 49, language: 'PHP' },
{ firstName: 'Odval', country: 'Mongolia', age: 38, language: 'Python' },
{ firstName: 'Emilija', country: 'Lithuania', age: 19, language: 'Python' },
{ firstName: 'Sou', country: 'Japan', age: 49, language: 'PHP' },
]
With the above example, the function needs to return this:
[
{ firstName: 'Gabriel', country: 'Monaco', age: 49, language: 'PHP' },
{ firstName: 'Sou', country: 'Japan', age: 49, language: 'PHP' },
]
I've looked at ways reduce() might work here as well, with no success.
I'm learning, and this is my 1st question here... please be gentle. xD
I've looked up every tutorial and search terms I can think of to learn this on my own. I don't want to just get the answer, but also, I'm hoping to learn why/how it works.
Thank you for your time.
list.filter((dev, age) => dev[age].includes(oldest)) doesn't make sense because age is not an outer variable, but a plain property - and the value is a number, not an array, so .includes won't work.
I'd use Math.max to first identify the highest age, then filter by the objects with that age.
const list = [
{ firstName: 'Gabriel', country: 'Monaco', age: 49, language: 'PHP' },
{ firstName: 'Odval', country: 'Mongolia', age: 38, language: 'Python' },
{ firstName: 'Emilija', country: 'Lithuania', age: 19, language: 'Python' },
{ firstName: 'Sou', country: 'Japan', age: 49, language: 'PHP' },
];
const findOldest = (list) => {
const maxAge = Math.max(...list.map(obj => obj.age));
return list.filter(obj => obj.age === maxAge);
};
console.log(findOldest(list));

Higher Order Function with filter and sort that finds specified property in object's array

I'm struggling to understand higher-order functions. I have an objects array and want to return the developer out of the following list that is the oldest. In case some have the same age, I want to return all of them.
let input = [
{ firstName: 'Gabriel', lastName: 'X.', country: 'Monaco', continent: 'Europe', age: 49, language: 'PHP' },
{ firstName: 'Odval', lastName: 'F.', country: 'Mongolia', continent: 'Asia', age: 38, language: 'Python' },
{ firstName: 'Emilija', lastName: 'S.', country: 'Lithuania', continent: 'Europe', age: 19, language: 'Python' },
{ firstName: 'Sou', lastName: 'B.', country: 'Japan', continent: 'Asia', age: 49, language: 'PHP' },
];
Output I'm looking for:
let output = [
{ firstName: 'Gabriel', lastName: 'X.', country: 'Monaco', continent: 'Europe', age: 49, language: 'PHP' },
{ firstName: 'Sou', lastName: 'B.', country: 'Japan', continent: 'Asia', age: 49, language: 'PHP' },
];
Here is my code:
let oldDevFirst = input.sort((a,b)=>ages= b.age-a.age)
let allOdldDev = oldDevFirst.filter(el=> el === el.age[0]) //oldest developer at el.age[0]
Basically I sorted the list with 'oldDevFirst' so that the oldest developer comes first. However, I don't know how I can compare every property to the first property to return all the developers, that have the same oldest age. Thanks for reading or even helping a beginner out!
You need to do this:
let input = [
{ firstName: 'Gabriel', lastName: 'X.', country: 'Monaco', continent: 'Europe', age: 49, language: 'PHP' },
{ firstName: 'Odval', lastName: 'F.', country: 'Mongolia', continent: 'Asia', age: 38, language: 'Python' },
{ firstName: 'Emilija', lastName: 'S.', country: 'Lithuania', continent: 'Europe', age: 19, language: 'Python' },
{ firstName: 'Sou', lastName: 'B.', country: 'Japan', continent: 'Asia', age: 49, language: 'PHP' },
];
let oldDevFirst = input.sort((a,b)=>ages= b.age-a.age)
let maxAge = oldDevFirst[0].age;
let allOdldDev = oldDevFirst.filter(el=> el.age === maxAge)
console.log(allOdldDev);
A better way would be finding the highest age, and then getting the list:
let input = [
{ firstName: 'Gabriel', lastName: 'X.', country: 'Monaco', continent: 'Europe', age: 49, language: 'PHP' },
{ firstName: 'Odval', lastName: 'F.', country: 'Mongolia', continent: 'Asia', age: 38, language: 'Python' },
{ firstName: 'Emilija', lastName: 'S.', country: 'Lithuania', continent: 'Europe', age: 19, language: 'Python' },
{ firstName: 'Sou', lastName: 'B.', country: 'Japan', continent: 'Asia', age: 49, language: 'PHP' },
];
let maxAge = Math.max.apply(Math, input.map(function(o) { return o.age; }))
let allOdldDev = input.filter(el=> el.age === maxAge)
console.log(allOdldDev);
You could take a single loop approach and look only for age and collect greater in a new array or same age in the same result set.
let input = [{ firstName: 'Gabriel', lastName: 'X.', country: 'Monaco', continent: 'Europe', age: 49, language: 'PHP' }, { firstName: 'Odval', lastName: 'F.', country: 'Mongolia', continent: 'Asia', age: 38, language: 'Python' }, { firstName: 'Emilija', lastName: 'S.', country: 'Lithuania', continent: 'Europe', age: 19, language: 'Python' }, { firstName: 'Sou', lastName: 'B.', country: 'Japan', continent: 'Asia', age: 49, language: 'PHP' }],
result = input.reduce((r, o, i) => {
if (!i || r[0].age < o.age) return [o];
if (r[0].age === o.age) r.push(o);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
let input = [
{
firstName: "Gabriel",
lastName: "X.",
country: "Monaco",
continent: "Europe",
age: 49,
language: "PHP",
},
{
firstName: "Odval",
lastName: "F.",
country: "Mongolia",
continent: "Asia",
age: 38,
language: "Python",
},
{
firstName: "Emilija",
lastName: "S.",
country: "Lithuania",
continent: "Europe",
age: 19,
language: "Python",
},
{
firstName: "Sou",
lastName: "B.",
country: "Japan",
continent: "Asia",
age: 49,
language: "PHP",
},
];
const heightage = input.map((i) => i.age)[0];
input.filter((item) => item.age === heightage);
use Math.max find the highest age value
use array filter to select the equal highest age value people
let input = [
{
firstName: "Gabriel",
lastName: "X.",
country: "Monaco",
continent: "Europe",
age: 49,
language: "PHP",
},
{
firstName: "Odval",
lastName: "F.",
country: "Mongolia",
continent: "Asia",
age: 38,
language: "Python",
},
{
firstName: "Emilija",
lastName: "S.",
country: "Lithuania",
continent: "Europe",
age: 19,
language: "Python",
},
{
firstName: "Sou",
lastName: "B.",
country: "Japan",
continent: "Asia",
age: 49,
language: "PHP",
},
];
const tMax = Math.max(...input.map(item => item.age));
const result = input.filter(item => item.age == tMax);
console.log(result);

Codewars Coding Meetup #6 - Can they code in the same language?

I'm starting very basic trying to approach this using for and if loops, rather than anything too advanced for myself. I am seeking a push in the right direction.
You will be given an array of objects (associative arrays in PHP)
representing data about developers who have signed up to attend the
next coding meetup that you are organising.
Your task is to return either:
true if all developers in the list code in the same language; or false
otherwise. For example, given the following input array:
var list1 = [
{ firstName: 'Daniel', lastName: 'J.', country: 'Aruba', continent: 'Americas', age: 42, language: 'JavaScript' },
{ firstName: 'Kseniya', lastName: 'T.', country: 'Belarus', continent: 'Europe', age: 22, language: 'JavaScript' },
{ firstName: 'Hanna', lastName: 'L.', country: 'Hungary', continent: 'Europe', age: 65, language: 'JavaScript' },
];
your function should return true.
My logic is that if every language in the array is equal to the very first one, then it should return true, as clearly they would all be the same, if not return false.
However when I run the code it returns only true and fails to return false, here is what I have:
function isSameLanguage(list) {
for (var i = 0; i < list.length; i++) {
if (list[i].language === list[0].language) {
return true;
}
}
return false;
}
In the simple language your codes means
if (list[i].language === list[0].language) {
return true;
}
The above part means that if list[i].language(any language) is equal to first element's language list[0].language then return true. So this is not what you want.
You want if any of the language list[i].language is not equal to first language list[0].language then return false
You should change condition from === to !== and then return false inside the loop
var list1 = [
{ firstName: 'Daniel', lastName: 'J.', country: 'Aruba', continent: 'Americas', age: 42, language: 'JavaScript' },
{ firstName: 'Kseniya', lastName: 'T.', country: 'Belarus', continent: 'Europe', age: 22, language: 'JavaScript' },
{ firstName: 'Hanna', lastName: 'L.', country: 'Hungary', continent: 'Europe', age: 65, language: 'JavaScript' },
];
function isSameLanguage(list) {
for (var i = 1; i < list.length; i++){
if (list[i].language !== list[0].language){
return false;
}
}
return true;
}
console.log(isSameLanguage(list1))
The problem with your logic is that it will return true as soon as it find a language that is similar to the 1st item. In addition, you start the iteration from the 1st item, which is identical to itself.
An easier option would be to use Array.every(), and check all items vs the 1st item. If any of them doesn't have a matching language, the function would return false.
const list1 = [
{ firstName: 'Daniel', lastName: 'J.', country: 'Aruba', continent: 'Americas', age: 42, language: 'JavaScript' },
{ firstName: 'Kseniya', lastName: 'T.', country: 'Belarus', continent: 'Europe', age: 22, language: 'JavaScript' },
{ firstName: 'Hanna', lastName: 'L.', country: 'Hungary', continent: 'Europe', age: 65, language: 'JavaScript' },
];
function isSameLanguage([start, ...rest]) {
return rest.every(o => o.language === start.language);
}
console.log(isSameLanguage(list1))

Javascript multiple filters array

My question is extension to this question javascript filter array multiple conditions
from that question if filter object is
{address: 'England', name: 'Mark'};
and array is
var users = [{
name: 'John',
email: 'johnson#mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark#mail.com',
age: 28,
address: 'England'
}
];
so the answer is
[
{
"name": "Mark",
"email": "mark#mail.com",
"age": 28,
"address": "England"
}
]
which is absolutely fine but my question is array has to be filtered for the filter object properties value
for example my filter object will be {address: 'England', name: ''} now this has to filter the array for all names and address England
You'd use filter on users and every on the filter object's entries
const filter = {address: 'England', name: 'Mark'};
const res = users.filter(user =>
Object.entries(filter)
.every(([k,v]) => v === '' || user[k] === v)
);
console.log(res);
<script>
var users = [{
name: 'John',
email: 'johnson#mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark#mail.com',
age: 28,
address: 'England'
}
];
</script>
From the example in the post you mention, just continue if the filter is blank
var filter = {address: 'England', name: ''}
var users = [{
name: 'John',
email: 'johnson#mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark#mail.com',
age: 28,
address: 'England'
}
];
users = users.filter(function(item) {
for (var key in filter) {
if (filter[key] == "") continue; // added this:
if (item[key] === undefined || item[key] != filter[key])
return false;
}
return true;
});
console.log(users)
You can use a combination of filter and every with some ternary logic to determine if the filter value is empty to get all.
var users = [{
name: 'John',
email: 'johnson#mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark#mail.com',
age: 28,
address: 'England'
}
];
var filter1 = {address: 'England', name: 'Mark'};
var filter2 = {address: 'England', name: ''};
function findResults(input, filterObj){
return input.filter(
item => Object.keys(filterObj)
.every(r => filterObj[r].length
? item[r] == filterObj[r]
: true)
)
}
console.log('with address and name', findResults(users,filter1));
console.log('with address only', findResults(users,filter2));
If I understand your question correctly you need following output.
If this what you are looking for Array.filter should suffice your use case.
Take a look at the code sandbox where I have created a function filterByObj which takes arr, filterObj as arguments and returns given output for { address: "England", name: "" }
You need you filter for this case.
var filter1 = {
address: 'England',
name: 'Mark'
};
var filter2 = {
address: 'England',
name: ''
};
var users = [
{
name: 'John',
email: 'johnson#mail.com',
age: 25,
address: 'USA'
},
{
name: 'Tom',
email: 'tom#mail.com',
age: 35,
address: 'England'
},
{
name: 'Mark',
email: 'mark#mail.com',
age: 28,
address: 'England'
}
];
function filterUser(arr, obj) {
return arr.filter(function(item) {
return (
(obj.address === '' || item.address === obj.address) &&
(obj.name === '' || item.name === obj.name)
);
});
}
console.log(filterUser(users, filter1));
console.log(filterUser(users, filter2));

Categories