I have the following array of employees. I want to create a new array employeeNames that has only the firstName and lastName properties. I believe I can do this with the map() method but I'm not exactly sure how.
let employees = { firstName: 'Collin', lastName: 'Sexton', email: 'exampe#test.com', dob: '03/20/1986' ... }
Resulting array should look like:
employeeNames = { firstName: 'Collin', lastName: 'Sexton' }
You are not looking for array as a result though.. do this
let { firstName, lastName } = employees;
let employeeNames = { firstName, lastName };
What we do here is called deconstruction. We bind the values of 'firstName' and 'lastName' to variables with the same name and then create a new Object with those variables. If no keys are given, it automagically names them after the variables.
Probably you meant you have array of objects. So you'd do:
const projected = empArray.map((empItem) => ({
firstName: empItem.firstName,
lastName: empItem.lastName,
}));
employees is an object which is not iterable, so you need to convert before being able to map() a new one.
Which can easity be made with Object.entries()
so..
// key is the object key while value is the object value of corresponding key
let newArray = Object.entries(employees).map((key, value) => {
let arrayEntry;
if (key === 'firstName' || key === 'lastName') {
newEntry = value;
}
return arrayEntry;
});
Your new array should then output to [John, Doe, Jane, Doe, name, lastname]
Here is how it will be if you need to map array of eployees to array with only needed props:
let employees = [{ firstName: 'Collin', lastName: 'Sexton', email: 'exampe#test.com', dob: '03/20/1986'}]
let result = employees.map({firstName, lastName}=> ({ firstName, lastName}));
Related
Let's suppose I have the following object:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
And that I want only the id and fullName.
I will do the following :
const { id, fullName } = user
Easy-peasy, right?
Now let's suppose that I want to do the destructuring based on the value of another variable called fields.
const fields = [ 'id', 'fullName' ]
Now my question is : How can I do destructuring based on an array of keys?
I shamelessly tried the following without success:
let {[{...fields}]} = user and let {[...fields]} = user. Is there any way that this could be done?
Thank you
It's not impossible to destructure with a dynamic key. To prevent the problem of creating dynamic variables (as Ginden mentioned) you need to provide aliases.
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
const {[fields[0]]: id, [fields[1]]: fullName} = user;
console.log(id); // 42
console.log(fullName); // { firstName: "John", lastName: "Doe" }
To get around the problem of having to define static aliases for dynamic values, you can assign to an object's dynamic properties. In this simple example, this is the same as reverting the whole destructuring, though :)
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user);
console.log(object.id); // 42
console.log(object.fullName); // { firstName: "John", lastName: "Doe" }
sources:
https://twitter.com/ydkjs/status/699845396084846592
https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md#not-just-declarations
Paul Kögel's answer is great, but I wanted to give a simpler example for when you need only the value of a dynamic field but don't need to assign it to a dynamic key.
let obj = {x: 3, y: 6};
let dynamicField = 'x';
let {[dynamicField]: value} = obj;
console.log(value);
Short answer: it's impossible and it won't be possible.
Reasoning behind this: it would introduce new dynamically named variables into block scope, effectively being dynamic eval, thus disabling any performance optimization. Dynamic eval that can modify scope in fly was always regarded as extremely dangerous and was removed from ES5 strict mode.
Moreover, it would be a code smell - referencing undefined variables throws ReferenceError, so you would need more boilerplate code to safely handle such dynamic scope.
As discussed before, you can't destruct into dynamically named variables in JavaScript without using eval.
But you can get a subset of the object dynamically, using reduce function as follows:
const destruct = (obj, ...keys) =>
keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});
const object = {
color: 'red',
size: 'big',
amount: 10,
};
const subset1 = destruct(object, 'color');
const subset2 = destruct(object, 'color', 'amount', 'size');
console.log(subset1);
console.log(subset2);
You can't destruct without knowing the name of the keys or using an alias for named variables
// you know the name of the keys
const { id, fullName } = user;
// use an alias for named variables
const { [fields[0]]: id, [fields[1]]: fullName } = user;
A solution is to use Array.reduce() to create an object with the dynamic keys like this:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName', 'age' ];
const obj = fields.reduce((acc, k) => ({ ...acc, ...(user.hasOwnProperty(k) && { [k]: user[k] }) }), {});
for(let k in obj) {
console.log(k, obj[k]);
}
I believe that the above answers are intellectual and valid because all are given by pro developers. :). But, I have found a small and effective solution to destructure any objects dynamically. you can destructure them in two ways. But both ways are has done the same action.
Ex:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
using "Object.key", "forEach" and "window" object.
Object.keys(user).forEach(l=>window[l]=user[l]);
Simply using Object. assign method.
Object.assign(window, user)
Output:
console.log(id, displayName, fullName)
// 42 jdoe {firstName: "John", lastName: "Doe"}
Anyway, I am a newbie in JS. So, don't take it as an offense if you found any misleading info in my answer.
Following code outputs {name: "Bob", surname: "Smith"} and it works fine. I want to know can I make it shorter.
((person = { name: 'Bob', surname: 'Smith', age: 22, }) => {
const {
name, // (a) create variable from deconstructing
surname,
} = person;
return {
name, // (b) reuse variable as new object parameter name (and value)
surname
}
})();
Can I somehow merge object deconstruction to variables (a) with returning a new object with Object Property Value shorthand (b)?
I use here shorthand but then its purpose is defeated by the need to manually re-use parameters. I want to mention the name or surname word in my function once not twice...
Destructure person in the function's declaration:
const result = (({ name, surname } = { name: 'Bob', surname: 'Smith', age: 22, }) => ({
name, // (b) reuse variable as new object parameter name (and value)
surname
}))();
console.log(result);
You can not mention it at all
((person = { name: 'Bob', surname: 'Smith', age: 22, }) => {
const {age,...ans} = person;
return ans
})()
Let's suppose I have the following object:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
And that I want only the id and fullName.
I will do the following :
const { id, fullName } = user
Easy-peasy, right?
Now let's suppose that I want to do the destructuring based on the value of another variable called fields.
const fields = [ 'id', 'fullName' ]
Now my question is : How can I do destructuring based on an array of keys?
I shamelessly tried the following without success:
let {[{...fields}]} = user and let {[...fields]} = user. Is there any way that this could be done?
Thank you
It's not impossible to destructure with a dynamic key. To prevent the problem of creating dynamic variables (as Ginden mentioned) you need to provide aliases.
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
const {[fields[0]]: id, [fields[1]]: fullName} = user;
console.log(id); // 42
console.log(fullName); // { firstName: "John", lastName: "Doe" }
To get around the problem of having to define static aliases for dynamic values, you can assign to an object's dynamic properties. In this simple example, this is the same as reverting the whole destructuring, though :)
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user);
console.log(object.id); // 42
console.log(object.fullName); // { firstName: "John", lastName: "Doe" }
sources:
https://twitter.com/ydkjs/status/699845396084846592
https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md#not-just-declarations
Paul Kögel's answer is great, but I wanted to give a simpler example for when you need only the value of a dynamic field but don't need to assign it to a dynamic key.
let obj = {x: 3, y: 6};
let dynamicField = 'x';
let {[dynamicField]: value} = obj;
console.log(value);
Short answer: it's impossible and it won't be possible.
Reasoning behind this: it would introduce new dynamically named variables into block scope, effectively being dynamic eval, thus disabling any performance optimization. Dynamic eval that can modify scope in fly was always regarded as extremely dangerous and was removed from ES5 strict mode.
Moreover, it would be a code smell - referencing undefined variables throws ReferenceError, so you would need more boilerplate code to safely handle such dynamic scope.
As discussed before, you can't destruct into dynamically named variables in JavaScript without using eval.
But you can get a subset of the object dynamically, using reduce function as follows:
const destruct = (obj, ...keys) =>
keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});
const object = {
color: 'red',
size: 'big',
amount: 10,
};
const subset1 = destruct(object, 'color');
const subset2 = destruct(object, 'color', 'amount', 'size');
console.log(subset1);
console.log(subset2);
You can't destruct without knowing the name of the keys or using an alias for named variables
// you know the name of the keys
const { id, fullName } = user;
// use an alias for named variables
const { [fields[0]]: id, [fields[1]]: fullName } = user;
A solution is to use Array.reduce() to create an object with the dynamic keys like this:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName', 'age' ];
const obj = fields.reduce((acc, k) => ({ ...acc, ...(user.hasOwnProperty(k) && { [k]: user[k] }) }), {});
for(let k in obj) {
console.log(k, obj[k]);
}
I believe that the above answers are intellectual and valid because all are given by pro developers. :). But, I have found a small and effective solution to destructure any objects dynamically. you can destructure them in two ways. But both ways are has done the same action.
Ex:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
using "Object.key", "forEach" and "window" object.
Object.keys(user).forEach(l=>window[l]=user[l]);
Simply using Object. assign method.
Object.assign(window, user)
Output:
console.log(id, displayName, fullName)
// 42 jdoe {firstName: "John", lastName: "Doe"}
Anyway, I am a newbie in JS. So, don't take it as an offense if you found any misleading info in my answer.
I have an array of objects that looks like:
{
name: 'steve',
plaintiff:'IRS'
amount: 5000,
otherliens:[
{
amount:5000,
plaintiff:'irs'
},
{amount:5000,
plaintiff:'irs'
}
]
}
i need to send this as a csv so i need to map and iterate over this subarray and flatten it into them ain object like so:
{
name:'steve',
plaintiff:'irs',
amount:5000,
plaintiff2:'irs',
amount2:5000,
plaintiff3:'irs',
amount3:5000
}
the code i use to normally do this process is by mapping the contents of the original array into a new array with arr.map(a,i =>{ a[i] ? a[i].amount = a[i].amount }) i am able to work the the subarrays that are string based by flat guessing a number of entries (see phones and emails) because if i return null it just returns blank, which in the csv isnt the worst thing. but i cannot do the same because accessing a sub property of an element that doesnt exist obviously wont work. So here is the map im using where emailAddresses is a string array, phoneNumbers is a string array and otherliens is an object array.
any help would be appreciated and bear in mind because it is bulk data transfer and csvs that will have a fixed number of columns in the end, i dont mind null values, so i guess you would take the longest subarray length and use that in all the other objects.
Full code
prospects.map((list, i) => {
result[i]
? (result[i].fullName = list.fullName)
(result[i].First_Name = list.firstName)
(result[i].Last_Name = list.lastName)
(result[i].Delivery_Address = list.deliveryAddress)
(result[i].City = list.city)
(result[i].State = list.state)
(result[i].Zip_4 = list.zip4)
(result[i].County = list.county)
(result[i].plaintiff= list.plaintiff)
(result[i].Amount = list.amount)
(result[i].age = list.age)
(result[i].dob= list.dob)
(result[i].snn= list.ssn)
(result[i].plaintiff2= list.otherliens[1].plaintiff )
(result[i].filingDate2= list.otherliens[1].filingDate)
(result[i].amount2= list.otherliens[1].amount )
(result[i].plaintiff3= list.otherliens[2].plaintiff)
(result[i].filingDate3= list.otherliens[2].filingDate )
(result[i].amount3= list.otherliens[2].amount )
(result[i].amount4= list.otherliens[3].amount)
(result[i].plaintiff4= list.otherliens[3].plaintiff )
(result[i].filingDate4= list.otherliens[3].filingDate )
(result[i].phone1 = list.phones[0])
(result[i].phone2 = list.phones[1])
(result[i].phone3 = list.phones[2])
(result[i].phone4 = list.phones[3])
(result[i].phone5 = list.phones[4])
(result[i].phone6 = list.phones[5])
(result[i].phone7 = list.phones[6])
(result[i].phone8 = list.phones[7])
(result[i].phone9 = list.phones[8])
(result[i].emailAddress1 = list.emailAddresses[0])
(result[i].emailAddress2 = list.emailAddresses[1])
(result[i].emailAddress3 = list.emailAddresses[2])
(result[i].emailAddress4 = list.emailAddresses[3])
(result[i].emailAddress5 = list.emailAddresses[4])
(result[i].emailAddress6 = list.emailAddresses[5])
(result[i].emailAddress7 = list.emailAddresses[6])
: (result[i] = {
Full_Name: list.fullName ,
First_Name: list.firstName,
Last_Name: list.lastName,
Delivery_Address: list.deliveryAddress,
City: list.city,
State: list.state,
Zip_4: list.zip4,
County: list.county,
dob: list.dob,
ssn:list.ssn,
age:list.age,
Amount: list.amount,
plaintiff: list.plaintiff,
filingDate: list.filingDate,
phone1:list.phones[0],
phone2:list.phones[1],
phone3:list.phones[3],
phone4:list.phones[4],
phone5:list.phones[5],
phone6:list.phones[6],
phone7:list.phones[7],
phone8:list.phones[8],
emailAddress1:list.emailAddresses[0],
emailAddress2:list.emailAddresses[1],
emailAddress3:list.emailAddresses[2],
emailAddress4:list.emailAddresses[3],
emailAddress5:list.emailAddresses[4],
emailAddress6:list.emailAddresses[5],
plaintiff2: list.otherliens[1].plaintiff,
amount2: list.otherliens[1].amount,
filingDate2: list.otherliens[1].filingDate,
plaintiff3: list.otherliens[2].plaintiff,
filingDate3: list.otherliens[2].filingDate,
amount3: list.otherliens[2].amount,
plaintiff4: list.otherliens[3].plaintiff,
amount4: list.otherliens[3].amount,
filingDate4: list.otherliens[3].filingDate,
})
} );
Use loops to assign properties from the nested arrays, rather than hard-coding the number of items.
I also don't see the need for the conditional expression. Since each input element maps directly to an output element, there won't already be result[i] that needs to be updated.
result = prospects.map(({fullName, firstName, lastName, deliveryAddress, city, state,zip4, county, plaintiff, amount, age, dob, ssn, otherliens, phones, emailAddresses}) => {
let obj = {
fullName: fullName,
First_Name: firstName,
Last_Name: lastName,
Delivery_Address: deliveryAddress,
City: city,
State: state,
Zip_4: zip4,
County: county,
plaintiff: plaintiff,
Amount: amount,
age: age,
dob: dob,
ssn: ssn
};
otherliens.forEach(({plaintiff, amount}, i) => {
obj[`plaintiff${i+2}`] = plaintiff;
obj[`amount${i+1}`] = amount;
});
phones.forEach((phone, i) => obj[`phone${i+1}`] = phone);
emailAddresses.forEach((addr, i) => obj[`emailAddress${i+1}`] = addr);
return obj;
})
Let's suppose I have the following object:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
And that I want only the id and fullName.
I will do the following :
const { id, fullName } = user
Easy-peasy, right?
Now let's suppose that I want to do the destructuring based on the value of another variable called fields.
const fields = [ 'id', 'fullName' ]
Now my question is : How can I do destructuring based on an array of keys?
I shamelessly tried the following without success:
let {[{...fields}]} = user and let {[...fields]} = user. Is there any way that this could be done?
Thank you
It's not impossible to destructure with a dynamic key. To prevent the problem of creating dynamic variables (as Ginden mentioned) you need to provide aliases.
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
const {[fields[0]]: id, [fields[1]]: fullName} = user;
console.log(id); // 42
console.log(fullName); // { firstName: "John", lastName: "Doe" }
To get around the problem of having to define static aliases for dynamic values, you can assign to an object's dynamic properties. In this simple example, this is the same as reverting the whole destructuring, though :)
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName' ];
const object = {};
({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user);
console.log(object.id); // 42
console.log(object.fullName); // { firstName: "John", lastName: "Doe" }
sources:
https://twitter.com/ydkjs/status/699845396084846592
https://github.com/getify/You-Dont-Know-JS/blob/master/es6%20%26%20beyond/ch2.md#not-just-declarations
Paul Kögel's answer is great, but I wanted to give a simpler example for when you need only the value of a dynamic field but don't need to assign it to a dynamic key.
let obj = {x: 3, y: 6};
let dynamicField = 'x';
let {[dynamicField]: value} = obj;
console.log(value);
Short answer: it's impossible and it won't be possible.
Reasoning behind this: it would introduce new dynamically named variables into block scope, effectively being dynamic eval, thus disabling any performance optimization. Dynamic eval that can modify scope in fly was always regarded as extremely dangerous and was removed from ES5 strict mode.
Moreover, it would be a code smell - referencing undefined variables throws ReferenceError, so you would need more boilerplate code to safely handle such dynamic scope.
As discussed before, you can't destruct into dynamically named variables in JavaScript without using eval.
But you can get a subset of the object dynamically, using reduce function as follows:
const destruct = (obj, ...keys) =>
keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {});
const object = {
color: 'red',
size: 'big',
amount: 10,
};
const subset1 = destruct(object, 'color');
const subset2 = destruct(object, 'color', 'amount', 'size');
console.log(subset1);
console.log(subset2);
You can't destruct without knowing the name of the keys or using an alias for named variables
// you know the name of the keys
const { id, fullName } = user;
// use an alias for named variables
const { [fields[0]]: id, [fields[1]]: fullName } = user;
A solution is to use Array.reduce() to create an object with the dynamic keys like this:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
const fields = [ 'id', 'fullName', 'age' ];
const obj = fields.reduce((acc, k) => ({ ...acc, ...(user.hasOwnProperty(k) && { [k]: user[k] }) }), {});
for(let k in obj) {
console.log(k, obj[k]);
}
I believe that the above answers are intellectual and valid because all are given by pro developers. :). But, I have found a small and effective solution to destructure any objects dynamically. you can destructure them in two ways. But both ways are has done the same action.
Ex:
const user = {
id: 42,
displayName: "jdoe",
fullName: {
firstName: "John",
lastName: "Doe"
}
};
using "Object.key", "forEach" and "window" object.
Object.keys(user).forEach(l=>window[l]=user[l]);
Simply using Object. assign method.
Object.assign(window, user)
Output:
console.log(id, displayName, fullName)
// 42 jdoe {firstName: "John", lastName: "Doe"}
Anyway, I am a newbie in JS. So, don't take it as an offense if you found any misleading info in my answer.