How to select an object from an array by id? - javascript

I have an object that contains an array called applicants:
const persons={"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}}
How can I return the item from the entities.applicants array by id?
I tried something like:
const applicantsById = persons.entities.applicants.find(a => a.id ===id)
console.log(applicantsById.get('16671520041'))
But I can't figure out how to pass in the id?
codepen

Using vanilla javascript:
You need to define what id is before you set your applicantsById variable. This way you can find an id in your array of objects which equals the id you defined.
const id = '16671520041';
const applicantsById = persons.entities.applicants.find(a => a.id === id);
You can extend this to a function if you wish to use this with multiple ids:
const persons = {"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}};
const getApplicantById = _id => persons.entities.applicants.find(({id}) => id === _id);
console.log(getApplicantById('16671520041')); // Abouli obj
console.log(getApplicantById('16671520039')); // Purdy obj
Or, using Lodash and ES6:
const persons = {"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}};
const id = "16671520041";
const res = _.find(persons.entities.applicants, {id});
console.log(res); // Abouli obj
<script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

applicantsById needs to be a function parametrized on the id
const persons={"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}}
const applicantsById = id => persons.entities.applicants.find(a => a.id ===id)
console.log(applicantsById('16671520041'))

You should create a function.
const applicantsById = (id) => persons.entities.applicants.find(a => a.id === id)
applicantsById('16671520041')
this will return you required result

You can either define your id before you do your find:
const id = '16671520041';
const applicantsById = persons.entities.applicants.find(a => a.id ===id)
Or you can define a function that accepts an id as an argument. The other answers have covered how to do this with modern ES6 arrow functions. If you're unfamiliar with them here's the ES5 function declaration-way of writing it. Here I've also passed in the persons data to the function.
const persons={"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}}
// Accept persons data, and an id
function getApplicantById(persons, id) {
// Return the found applicant from the function
return persons.entities.applicants.find(a => a.id ===id);
}
// Pass in the data, and the id to the function
const applicant = getApplicantById(persons, '16671520041');
console.log(applicant);

Use filter for this
const persons={"entities":{"applicants":[{"lastName":"Agamemnon","isPrimaryApplicant":false,"id":"16671520038"},{"lastName":"Purdy","isPrimaryApplicant":true,"id":"16671520039"},{"lastName":"Brekky","isPrimaryApplicant":true,"id":"16671520040"},{"lastName":"Abouli","isPrimaryApplicant":true,"id":"16671520041"}]}}
console.log(get(16671520039));
function get(id)
{
return persons.entities.applicants.filter((e)=>e.id===id)
}

Related

How to append deleted from array elements by slice method?

How to delete elements from start of array and append them into end ?
const ImageArray = [i1,i2,i3,i4,i5]
const clickHandler = (index: number) => {
let start = ImageArray.slice(index)
let end = ImageArray....
let result = start.concat(end)
return result
}
{ImageArray.map((image, index) => (
<div
onClick={() => clickHandler(index)}
key={index} style={{backgroundImage: 'url('+image+')'}}
/>
))}
P.S. It's not necessary to use slice method
With x being the index clicked :
const arr = [0,1,2,3,4];
const newArr = [...arr.slice(1), ...arr.slice(0, 1)]
You can do:
const arr = ['i1','i2','i3','i4','i5']
const clickHandler = i => [...arr.slice(i), ...arr.slice(0, i)]
console.log('i3:', clickHandler(2)) // Clicked: 'i3'
Your function is designed to return a new array, but the place where you call the function is not doing anything with the returned value.
I assume you want to mutate ImageArray. In that case use splice to delete the first part, and push to append that same part at the end:
const clickHandler = (index: number) => {
ImageArray.push(...ImageArray.splice(0, index));
};
You can try splice instead
const clickHandler = (index) => ImageArray.push(...ImageArray.splice(0, index))
In case if you are working with a state and doesn't want to mutate original array, try to spread ImageArray to make not deep copy of it
const clickHandler = (index) => {
const arrCopy = [...ImageArray];
arrCopy.push(...arrCopy.splice(0, index));
return arrCopy;
}
array.splice(index).concat(array.splice(array.length - index))

Javascript - Retrieve the value of an object based on the ID of another object

I have an array of objects 'assignmentResults' as follows:
[
{'id':'1','skillIds':[1, 2]},
{'id':'2','skillIds':[2,3]}
And I also have an array of skills:
[
{'id':'1','name':skill1},
{'id':'2','name':'skill2',
{'id':'3','name':'skill3'}
With this information I would like to return the skillIds from assignmentResults as a name from the skills. For example if the value of skillIds (from assignmentResults) is [1,2], It'll return 'skill1' and 'skill2'. I tried to experiment with various JS array functions using .map, .filter and .find, but I haven't been able to achieve this result. I'm using vue JS to achieve this which through the following computed properties I'm retrieving the data mentioned above:
const searchResults = computed(() => {
return store.getters.getSearchResults
});
const skillList = computed(() => {
return root.$store.getters.getSkills
});
I have been going at it for a while and I'd really appreciate your help.
This should be easy.
var data =[
{'id':'1','name':"skill1"},
{'id':'2','name':'skill2'},
{'id':'3','name':'skill3'}
]
const getSkills =(ids)=>{
return data.filter(x=> ids.includes(parseInt(x.id))).map(x=> x.name);
}
console.log(getSkills([1,3]))
Give this a try:
const assignmentResults = [
{'id':'1','skillIds':['1','2']},
{'id':'2','skillIds':['2','3']}
];
const skills = [
{'id':'1','name':'skill1'},
{'id':'2','name':'skill2'},
{'id':'3','name':'skill3'}
];
const skillsForAssignment = (assignment) => assignmentResults
.find(ar => ar.id === assignment).skillIds
.map(sid => skills.find(sk => sk.id === sid).name);
console.log(skillsForAssignment("1"));
console.log(skillsForAssignment("2"));
//example assignments
const assignments = [
{'id':'1','skillIds':[1, 2]},
{'id':'2','skillIds':[2,3]},
{'id':'4','skillIds':[4,5]}
];
//example skills
const skills = [
{'id':'1','name':'skill1'},
{'id':'2','name':'skill2'},
{'id':'3','name':'skill3'}
];
//function gets the skill names from the assignments at the selected assignments id
function getSkillNames(reqId, assignments, skills){
const skillids = assignments.filter((a) => a.id === reqId.toString()).map((b) => b.skillIds)[0];
//if skillids are not undefined, do a search of skills, if found return
//names else empty array
if(skillids !== undefined)
return skills.filter((a) => skillids.includes(parseInt(a.id))).map((b) => b.name) || [];
else //return empty array
return [];
}
console.log(getSkillNames(1, assignments, skills));
console.log(getSkillNames(4, assignments, skills));

Filter array with hooks explanation?

Can someone explain to me why this is not filtering toDoList
const handleDelete = e => {
const { id } = e.currentTarget.parentElement;
toDoList.filter(element => element._id !== id);
setToDoList([...toDoList]);
};
While this is:
const handleDelete = e => {
const { id } = e.currentTarget.parentElement;
setToDoList(toDoList.filter(element => element._id !== id));
};
The reason behind that is Array.prototype.filter() returns the new filtered array at the end. Read from the documentation:
The filter() method creates a new array with all elements that pass the test implemented by the provided function.
In the second example you are passing it to setToDoList meanwhile in the first, the code is just calling it but not assigning to a variable.
Consider the following:
const toDoList = [{id: 1, name: 'first'}, {id: 2, name: 'second'}];
const id = 1;
toDoList.filter(element => element.id !== id);
console.log('original toDoList:', toDoList);
const result = toDoList.filter(element => element.id !== id);
console.log('filtered result:', result);
I hope that helps!
filter() does not updates the reference array but returns a new array so in first scenarion, you are filtering and not saving the filtered output and hence setting same value again while in second scenarion, you are passing return filtered values to setter

Replace map() with reduce() function

I try to replace map to reduce but without success. Can you help me rewrite this piese of code:
this.tares = this.tares
.map(tare => {
let suppliers = [];
this.organizations.forEach(organization => {
if (organization.tare_ids.indexOf(tare.id) !== -1) {
suppliers = suppliers.concat(tare.suppliers);
}
});
return { ...tare, suppliers };
});
My supplier variable as an accumulator parameter of a reduce function but in this case, I can't figure out how to apply reduce. Nested arrays crashing me.
You could take a Set for all id and map the array with an object and a check if id exists.
var ids = this.organizations.reduce(
(s, { tare_ids }) => tare_ids.reduce((t, id) => t.add(id), s),
new Set
);
this.tares = this.tares.map(tare => ({ ...tare, suppliers: ids.has(tare.id) ? tare.suppliers : [] }));

Lodash Group array of object and return array of key instead of object

I have an array of objects like this
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"}]
Using _.groupBy(data,"age") will return name as a key with array of object.
How do I return only array of name?
Use Array#reduce
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"}]
const res = data.reduce((a,{name,age})=>{
if(!a[age]) a[age] = [];
a[age].push(name);
return a;
}, {});
console.log(res);
UPDATE
Thanks for help , i need a key to be age and a value to be array of
only names instead of object , i have edited my question
In this case you can use reduce
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"},{name:'abc', age:'23'}]
const op = data.reduce((out,{name,age})=>{
if(out[age]){
out[age].push(name)
} else {
out[age] = [name]
}
return out
},{})
console.log(op)
Simply you can use map
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"}]
const op = data.map(({name}) => name)
console.log(op)
As #ori asking for unique names you can use Set if you want unique one only
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"},{name:'abc', age:'23'}]
const op = [...new Set(data.map(({name}) => name))]
console.log(op)
Use _.flow() to create a function that groups by age, then map the groups with _.mapValues(), and use _.map() to pluck the names from the arrays:
const { flow, groupBy, mapValues, map } = _
const fn = flow(
arr => groupBy(arr, 'age'),
groups => mapValues(groups, g => map(g, 'name'))
)
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"}]
const result = fn(data)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
And the terser lodash/fp version:
const { flow, groupBy, mapValues, map } = _
const fn = flow(
groupBy('age'),
mapValues(map('name'))
)
const data = [{name:"abc",age:"18"},{name:"dfd",age:"18"},{name:"dnss",age:"20"},{name:"dnnns",age:"12"}]
const result = fn(data)
console.log(result)
<script src='https://cdn.jsdelivr.net/g/lodash#4(lodash.min.js+lodash.fp.min.js)'></script>
after grouping you need to iterate every group and return only name:
const res = _.chain(data)
.groupBy('age')
.mapValues(group => _.map(group, 'name'))
// or with FP .mapValues(_.partial(_.map, _, 'name'))
.value();

Categories