Using Underscore (technically Lodash). Have an object that looks like the following.
var myObj = {
first: {name: 'John', occupation: 'Welder', age: 30},
second: {name: 'Tim', occupation: 'A/C Repair', kids: true},
third: {name: 'Dave', occupation: 'Electrician', age: 32},
fourth: {name: 'Matt', occupation: 'Plumber', age: 41, kids: false}
};
I also have a hash of arrays that I want to "clean" out of each object:
var excludes = {
first: ['name', 'age'],
second: ['occupation'],
fourth: ['kids]
};
The idea is that each of the elements in the array will be dropped from the object that has the matching key. Meaning my data will end up like this:
{
first: {occupation: 'Welder'},
second: {name: 'Tim', kids: true},
third: {name: 'Dave', occupation: 'Electrician', age: 32},
fourth: {name: 'Matt', occupation: 'Plumber', age: 41}
};
I was originally trying:
_.map(myObj, function(obj, k) {
if(_.has(excludes, k) {
// not sure what here
}
});
I was thinking of using omit at the innermost level, but I can only drop one key at a time, not a list of keys.
Actually, _.omit can take a list of keys:
result = _.transform(myObj, function(result, val, key) {
result[key] = _.omit(val, excludes[key]);
});
Related
I have an object like this:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
I tried to filter the object to show only the author with age above 35. This is what I expected:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}]}
However since the array is inside a non-array object, I cannot use filter() yet. How to approach this?
This is helpful in case you have more than one variable that keeps the same:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
obj = {
...obj,
author: obj.author.filter( x => x.age >= 35)
}
console.log(obj)
Although I recommend keeping the original obj and create a new one for the filtered obj:
var obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]}
const above35 = {
...obj,
author: obj.author.filter( x => x.age >= 35)
}
console.log(obj,"and",above35)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
obj.author = obj.author.filter(checkAge); // this will return an array with 1 object.
function checkAge(author) {
return author.age >= 35;
}
One simple way would be like this:
var obj = {
name: "Lesson I",
author: [
{ name: "Thomas", age: "40" },
{ name: "Richard", age: "33" },
],
};
const result = obj.author.filter((ob) => ob.age > 35);
obj.author = result;
console.log(obj);
One way...declare a new object with each key/value of the original object, but filter() the author value:
let obj = {name: 'Lesson I', author: [{name: 'Thomas', age: '40'}, {name: 'Richard', age: '33'}]};
let obj_old_authors = {
name: obj.name,
author: obj.author.filter(author => 35 < author.age)
};
console.log(obj_old_authors);
People is my model, data is my new information, and the forEach is how I am trying to insert the new data into my model, but formatted to only the information I care about
people = [{name: '', age: 0}];
data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
data.forEach(person => {
people.push({
name: person.name,
age: person.age,
});
});
However, the result I get is this:
people = [
{name: '', age: 0},
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
I'm trying to have the object array look like this instead:
people = [
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
However, I would like to know if theres a way to do it without an extra line of code (like popping the first element), and if theres a way to do it in one command? If not, I am open to suggestions. Thank you!
You're using the original array and not only that but also you're mutating the array.
You can use the function Array.prototype.map in order to generate a new array with the desired data.
const people = [{name: '', age: 0}];
const data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
const result = data.map(person => ({
name: person.name,
age: person.age,
}));
console.log(result);
You can also keep the desired keys and by using the functions Array.prototype.map and Array.prototype.reduce you can build the expected result:
const model = ["name", "age"];
const data = [
{id: '123', name: 'Bob', lastName: 'Guy', age: 40},
{id: '321', name: 'Michael', lastName: 'Park', age: 20},
]
const result = data.map(person => model.reduce((r, m) => ({...r, [m]: person[m]}), {}), []);
console.log(result);
Just in case you need to implement different person models, you can dinamically create the objects like this
peopleModel = [{ name: "", age: 0 }];
data = [
{ id: "123", name: "Bob", lastName: "Guy", age: 40 },
{ id: "321", name: "Michael", lastName: "Park", age: 20 },
];
const keysArr = Object.keys(peopleModel[0]);
const totalKeys = keysArr.length;
const people = data.reduce((acc, personObj) => {
const obj = {};
keysArr.forEach((key) => {
if (personObj[key]) {
obj[key] = personObj[key];
}
});
acc.push(obj);
return acc;
}, []);
console.log(people);
/* logs [
{name: 'Bob', age: 40},
{name: 'Michael', age: 20}
];
*/
but if you need a different model like
peopleModel = [{ name: "", age: 0, lastName: "" }]
you will get for the log the following:
[
{name: 'Bob', age: 40, lastName: 'Guy'},
{name: 'Michael', age: 20, lastName: 'Park'}
];
that way you do not need to hardcode the keys
I had this question on an exam and I got it wrong and I have been trying my best reading through MDN Web Docs but being only a week into learning JavaScript I have no clue what I am looking for.
This what I can recall from my exam, it this fictional state only 15-year-olds and above can be babysitters. I had used a ".find()" and I only could produce 1 person and it gave me the whole object and they just wanted the name. Gave a day in a half to find the answer myself but I am lost. HELP!
If you also have a link so I can read up more on this it will be helpful, because other students said they had similar and they asked them to average all the age instead. Arrays and Objects have me wanting to bang my head against the wall already.
function legalBabysitter(sitters){
};
/*Do not modify anything below this line*/
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
console.log(legalBabysitter(babysitterArray)); // should produce [Paul, Mary]
You can use fitler and map like this return sitters.filter(c=>c.age >= 15).map(c=>c.name);
function legalBabysitter(sitters){
return sitters.filter(c=>c.age >= 15).map(c=>c.name);
};
/*Do not modify anything below this line*/
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
console.log(legalBabysitter(babysitterArray)); // should produce [Paul, Mary]
If you need only for exam, you can use for loop, it is very clear.
function legalBabysitter(sitters){
var result = [];
for(var i =0; i < sitters.length; i ++){
if(sitters[i].age >= 15){
result.push(sitters[i].name);
}
}
return result;
};
function legalBabysitter(sitters){
var result = [];
for(var i =0; i < sitters.length; i ++){
if(sitters[i].age >= 15){
result.push(sitters[i].name);
}
}
return result;
};
/*Do not modify anything below this line*/
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
console.log(legalBabysitter(babysitterArray)); // should produce [Paul, Mary]
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
function legalBabysitter(sitters){
return sitters.filter(_ => _.age > 14).map(_ => _.name)
};
console.log(legalBabysitter(babysitterArray))
If you don't know .filer and .reduce, you can do it by .forEach.
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
function legalBabysitter(sitters){
let target = [];
sitters.forEach(_ => {
if (_.age > 14) target.push(_.name)
})
return target;
};
console.log(legalBabysitter(babysitterArray))
You can use reduce
Here idea is
Loop through array
Check if age is greater than or equal to 15 than add name to op
else keep it as it is
return op from function
function legalBabysitter(sitters){
return sitters.reduce((op,inp)=>{
if(inp.age >= 15){
op.push(inp.name)
}
return op
},[])
};
/*Do not modify anything below this line*/
const babysitterArray = [
{name: 'Peter', age: 13},
{name: 'Paul', age: 15},
{name: 'Mary', age: 17}
];
console.log(legalBabysitter(babysitterArray)); //
I have two arrays which have two different lengths.
For example:
var array1 = [{name: 'Yuri', age: 2, gender: 'Male'}, {name: 'Akit', age: 19, gender: 'Male'}, {name: 'Kean', age: 14, gender: 'Female'}, {name: 'Jan', age: 29, gender: 'Male'}, {name: 'Max', age: 25, gender: 'Male'}, {name: 'Suzy', age: 20, gender: 'Female'}];
var array2 = [{name: 'Jan', gender: 'Male', occupation: 'Designer'}, {name: 'Max', gender: 'Male', occupation: 'Developer'}, {name: 'Suzy', gender: 'Female', occupation: 'Tester'}];
array1's length is 5 and array2's length is 3. I want to run a loop on both arrays and match the name. If the name matches then I want to extract the that particular object from 2nd array. As they have different lengths loop is breaking at the first array length and not reaching 2nd array's last element. I am running the for loop based on array2 length. Please help me with this.
Expected result:
Name of both arrays should be matched and create another array as below
var array3 = [{name: 'Jan',age: 29, gender: 'Male', occupation: 'Designer'},
same for other objects]
You could take a Set for one array's names and filter the second array.
var array1 = [{name: 'Yuri', age: 9, gender: 'Male'}, {name: 'Akit', age: 19, gender: 'Male'}, {name: 'Kean', age: 14, gender: 'Female'}, {name: 'Jan', gender: 'Male'}, {name: 'Max', gender: 'Female'}],
array2 = [{name: 'Jan', age: 9, gender: 'Male'}, {name: 'Max', age: 19, gender: 'Male'}, {name: 'Suzy', age: 14, gender: 'Female'}],
set2 = new Set(array2.map(({ name }) => name)),
result = array1.filter(o => set2.has(o.name));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
var arr1 = [{name: 'Jan', age: 19}, {name: 'Suzy', age: 29}, {name: 'Peter', age: 39}, {name: 'Bart', age: 49}, {name: 'John', age: 59}];
var arr2 = [{name:'Kean', job: 'Technician'},{name:'Nick', job:'Mathematics'},{name: 'Jan', job: 'Tester'}, {name: 'Suzy', job:'Developer'}, {name: 'Peter', job: 'Scrum master'}];
result = arr1.map(x=> {
y = arr2.find(z=> x.name == z.name);
x.job = y ? y.job : undefined;
return x;
});
I've got this object:
var obj = {
family : [{name: 'will', age: 30}, {name: 'husain', age: 12}],
friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}],
school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]
}
convert it into this
var obj = [
{family : [{name: 'will', age: 30}, {name: 'husain', age: 12}]},
{friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}]},
{school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]}
];
Write now I am using for..in to build a new array and create object with key as key for new object and so on.
I'm doing this right now
var arr = [];
for (let key in obj) {
arr.push({key: obj[key]})
}
I think Object.keys is your best option:
var obj = {
family : [{name: 'will', age: 30}, {name: 'husain', age: 12}],
friends : [{name: 'cody', age: 31}, {name: 'jeff', age: 11}],
school : [{name: 'daniel', age: 20}, {name: 'carl', age: 15}]
}
var r = Object.keys(obj).map(x => ({[x]: obj[x]}) )
console.log(r)