map nested array into parent object's key value pairs - javascript

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;
})

Related

How do I sort some HTML elements alphabetically?

function render() {
let lastContact = listadeContatos.slice(-1);
boxapp__contact.innerHTML += lastContact
.map((contact) => {
return `<div class="box-app__contacts-list" id=${
contact.id
} onclick="boxapp(this.id)">
<div class="contact__nameinitial">${contact.fistName[0].toUpperCase()}</div>
<div class="contact__name">${contact.fistName}</div>
</div>`;
}).join("");
const contacts = document.querySelector(".box-app__contacts-list");
const c = [...document.querySelectorAll(".contact__name")];
if (listadeContatos.length > 1) {
c.sort((a, b) => (a.innerText > b.innerText ? 1 : -1)).forEach((node) => {
contacts.appendChild(node);
});
}
}
I made a simple app, a list of contacts, and I wanted them to be sorted alphabetically when a new
contact is added and called for rendering, but nothing I've tried has worked. And the similar issues I encountered were not enough for me to find the way to a solution. I'm still learning Javascript. I would like someone to help me if they can. And sorry if there are any spelling mistakes. I'm using Google Translate to make this post.
Try using this sort function: c.sort((a, b) => (a.innerText < b.innerText? -1 : a.innerText > b.innerText? 1 : 0))
Have a function that sorts array of objects with .sort() and .localeCompare() first, then render the HTML with a seperate function. If the data is changed in any way, you use those two functions the same way every time. This pattern is less error prone as long as the data doesn't vary in keys or pattern.
Details are commented in example
const contactData = [{
firstName: "Brandon",
lastName: "Grewe",
phone: ["205-116-8677", "961-849-8402", "112-125-1509"],
email: ["sgrewe0#rediff.com"]
}, {
firstName: "Lyndsay",
lastName: "Courtes",
phone: ["559-585-5161", "244-413-5832", "467-871-0638"],
email: ["lcourtes1#sun.com"]
}, {
firstName: "Rose",
lastName: "Xavier",
phone: ["293-858-6159"],
email: ["gpopley2#uol.com.br", "gpopley2#npr.org"]
}, {
firstName: "Berni",
lastName: "Molen",
phone: ["944-271-6491", "911-107-2055", "429-553-3494"],
email: ["bmolen3#gnu.org"]
}, {
firstName: "Rose",
lastName: "Fereday",
phone: ["820-272-1567"],
email: ["rfereday4#naver.com"]
}, {
firstName: "Juliana",
lastName: "Fredi",
phone: ["268-283-9358", "981-219-0701", "326-164-3537"],
email: ["jfredi5#bigcartel.com", "jfredi5#exblog.jp"]
}, {
firstName: "Barry",
lastName: "Gatchel",
phone: ["762-132-3931", "840-627-2075", "654-204-6164"],
email: ["mgatchel6#com.com"]
}, {
firstName: "Jeth",
lastName: "Harwin",
phone: ["871-777-0358", "968-282-0040"],
email: ["jharwin7#yahoo.co.jp", "jharwin7#icq.com"]
}, {
firstName: "Ahmad",
lastName: "Scoon",
phone: ["392-928-5655"],
email: ["ascoon8#ask.com", "ascoon8#nyu.edu"]
}, {
firstName: "Kristine",
lastName: "Sleet",
phone: ["104-606-6882"],
email: ["ksleet9#fc2.com", "ksleet9#php.net"]
}];
// Pass in an array of objects
function arrange(array) {
// Returns an object of arrays -- each keyed to a letter A-Z
let letters = Object.fromEntries(
[...new Array(26)]
.map((_, i) => i + 65)
.map(n => [String.fromCharCode(n), []])
);
//console.log(letters);
/*
Takes the given array and gets the first letter of each firstName
property then finds the array with that letter inside the letters
object and adds the current object to it's array -- once in
the array, it is sorted alphabetically by firstName or
lastName should firstName be identical
*/
array.forEach(con => {
let alpha = con.firstName.charAt(0);
letters[alpha].push(con)
letters[alpha].sort(
(a, b) => a.firstName.localeCompare(b.firstName) == 0 ?
a.lastName.localeCompare(b.lastName) :
a.firstName.localeCompare(b.firstName)
)
});
//console.log(letters);
// Filters out any letters that have empty arrays
letters = Object.fromEntries(Object.entries(letters)
.filter(sub => sub[1].length > 0)
);
//console.log(letters);
return letters;
}
// Pass in the object returned from arrange() and an optional DOM object
function build(object, node = document.body) {
/*
For each key of object render a <fieldset> and add the letter
to it's <legend> and it's #id
*/
Object.keys(object).forEach(letter => {
const alphabet = `
<fieldset id='${letter}' class='letter'>
<legend>${letter}</legend>
</fieldset>`;
node.insertAdjacentHTML('beforeend', alphabet);
});
// Make an array of the <fieldset>s
const letters = [...document.querySelectorAll('.letter')];
/*
For each <fieldset> find the array of the object that
corresponds to the <fieldset>'s #id. For each object of the
sub-array interpolate the object's data within the template
literals, then render the template literal to the current <fieldset>
*/
letters.forEach(az => {
let group = object[az.id].map(contact => {
const fullName = `
<fieldset class='contact'>
<legend>
${contact.firstName}
${contact.lastName}
</legend>
<menu>`;
const numbers = contact.phone.map(tel => `
<li>Phone:
<output name='phone'>${tel}</output>
</li>`
).join('');
const address = contact.email.map(pop => `
<li>Email:
<output name='email'>${pop}</output>
</li>`
).join('');
return `${fullName}${numbers}
</menu><menu>${address}</menu>
</fieldset>`;
});
az.insertAdjacentHTML('beforeend', group.join(''));
});
}
const data = arrange(contactData);
build(data);

How to check in array if it contains given element

I am trying below code but its not working so first am trying to get a person department Name currently, hard coded it to check
var arr=[]
let CurrDept = "AB-CDE-F";
var Detept=CurrDept.substring(0,5);
arr.push(Detept)
Now in below line of code i am trying this line so it should exclude all results which start from AB-CD
var Userprofiledept=data.value[0].UserId.Department;
const isInArray = arr.indexOf(Userprofiledept) > -1;
isInArray should be false which can be put in my condition but it always give true
Can anyone help ?
So current user department may be AB-CDE-F and data i am getting from my rest call may have lots of department for many users AB-CDE-F,AB-CDE-F,AB-CDE,AB-CD,AB-C
so only want to exclude results which are AB-CDE-F,AB-CDE-F,AB-CDE,AB-CD as they are starting with AB-CD
You can use Array.prototype.filter and String.prototype.startsWith.
const
data = {value: [{ UserId: { ID: 14, Email: "sdfds", Department: "AB-CD-EF" } }, { UserId: { ID: 14, Email: "sdfds", Department: "AB-CD" } }, { UserId: { ID: 14, Email: "sdfds", Department: "AB-C" } }]},
discard = "AB-CD",
res = data.value.filter((v) => !v.UserId.Department.startsWith(discard));
console.log(res);
You could move the functionality into a function and check if the substring exists and add, if necessary.
const
add = string => {
string = string.slice(0, 5);
if (array.includes(string)) return;
array.push(string);
}
array = [];
add('AB-CDE-F');
console.log(array);
add('AB-CDE-F');
console.log(array);
add('AB-CDE');
console.log(array);

Map specific properties from an array into a new array

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}));

Convert Array with objects to manipulate

I'm trying to manipulate this array and play with parse, push and save data commands. but for some reason is not reading.
Any help?
I'm super new to it and just trying to practice.
Should be an array of objects.
var employeeString = [
{ first_name: 'Josh', last_name:'Neil', nationality:'Indian'},
{ first_name: 'Brian', last_name:'Cok', nationality:'Canadian'},
{ first_name: 'Katja', last_name:'Fanta', nationality:'German'}
];
var jsonValues = JSON.stringify(employeeString);
current_values = JSON.parse(jsonValues);
var nationality = [];
//console.log (current_values);
for ( i = 0; i < current_values.length; i++) {
var currentItem = current_values[i]
var first_name = currentItem['first_name'];
var last_name = currentItem['last_name'];
//push value into array
nationality.push(currentItem['nationality']);
if (currentItem == 'first_name' || currentItem == 'last_name') {
return id[i+1];
}
}
console.log (first_name , last_name);
You don't need to parse the already JSON object.
For example JSON.parse('[{x:10},{y:20}]'); will return JSON object from the string. This step is required to access the value of x and y, which are in string form as you can see '' around it. But in your case, you already got a JSON Object you don't need to parse it again.
Further in console.log if you want to print first_name, do not add '' around it. Here is your working code
var current_values = [
{ first_name: 'Josh', last_name: 'Neil', Nationality: 'Indian' },
{ first_name: 'Brian', last_name: 'Cok', Nationality: 'Canadian' },
{ first_name: 'Katja', last_name: 'Fanta', Nationality: 'German' }
];
// current_values = JSON.parse(employeeString);
// console.log(current_values);
for (i = 0; i < current_values.length; i++) {
var currentItem = current_values[i]
var first_name = currentItem['first_name'];
var last_name = currentItem['last_name'];
console.log(first_name, last_name);
}
The JSON.parse method accepts a string, but you're giving it an array of objects.
var values = JSON.parse("[{'first_name': 'Josh', ...}, ...]");
Would work better.
In general, parsing will convert a string to objects. http://www.willamette.edu/~fruehr/haskell/seuss.html
The data type for employeeString is Array, but JSON.parse() is supposed to parse JSON data. So, you can first change employeeString into a JSON data before parse it.
You don't need to JSON.parse(employeeString), since it is already an object.
JSON.parse is used to create objects from their string representation, e.g. parse the string '{"prop":42}' to an actual object with a property prop and its value being 42. Since employeeString in your code is already an object, you don't need to JSON.parse it again.
BTW, you probably meant this:
// notice that this is now an actual string
var employeeString = `[
{ first_name: 'Josh', last_name:'Neil', Nationality:'Indian'},
{ first_name: 'Brian', last_name:'Cok', Nationality:'Canadian'},
{ first_name: 'Katja', last_name:'Fanta', Nationality:'German'}
]`;

compare keys of two objects and construct a third one with same keys to reflect the difference

I am trying to compare two objects and construct a third one if the value stored in a property of one is different than the other. If not I am storing an empty string. The way am doing it in my opinion is super inefficient and non sustainable. This wont work if the keys change or their number increases. I have to be able to do this programmatically with pure JS, no jQuery:
var staleProfile = {
firstName: 'john',
lastName: 'smith',
email: 'js#gmail.com'
}
var CurrentCustomer = {};
CurrentCustomer.profile = {
firstName: 'paul',
lastName: 'smith',
email: 'js#yahoo.com'
}
var returnObj = {};
returnObj.firstName = staleProfile.firstName != CurrentCustomer.profile.firstName ? CurrentCustomer.profile.firstName : ''
returnObj.lastName = staleProfile.lastName != CurrentCustomer.profile.lastName ? CurrentCustomer.profile.lastName : ''
returnObj.email = staleProfile.email != CurrentCustomer.profile.email ? CurrentCustomer.profile.email : ''
This searches for all the object keys in the CurrentCustomer.profile and checks for differences to the staleProfile. It adds keys to the diff, that only exist in object1 but not in object0, but doesn't take care of keys that are removed from object0to object1.
var staleProfile = {
firstName: 'john',
lastName: 'smith',
email: 'js#gmail.com',
key0: 'value0'
}
var CurrentCustomer = {};
CurrentCustomer.profile = {
firstName: 'paul',
lastName: 'smith',
email: 'js#yahoo.com',
key1: 'value1'
}
function createDiffObject(object0, object1) {
var diff = {};
Object.keys(object1).forEach(function(key) {
if (!object0.hasOwnProperty(key) || object0[key] != object1[key]) {
diff[key] = object1[key];
} else {
diff[key] = '';
}
});
return diff;
}
console.log(createDiffObject(staleProfile, CurrentCustomer.profile));
// output:
/*
{ firstName: 'paul',
lastName: '',
email: 'js#yahoo.com',
key1: 'value1' }
*/
An option would be to get all the keys present in your object using Object.keys(staleProfile).
After this you can loop through the keys and compare values. See an example down below.
var keys = Object.keys(staleProfile),
i, j,
comparedObject = {},
key,
CurrentCustomer = {
a:a,
b:b,
c:c
};
for (i = 0, j = keys.length; i < j; i++) {
key = keys[i];
if (staleProfile[key] === CurrentCustomer[key]) {
comparedObject[key] === CurrentCustomer[key];
} else {
comparedObject[key] === '';
}
}
One way to do it is to make a small helper function to assign each property (or empty string):
// NOTE: staleProfile and CurrentCustomer are assumed to be in the scope above
// If this could be an issue, just pass them as parameters
function getProp(prop) {
let staleProp = staleProfile[prop];
let currProp = CurrentCustomer.profile[prop];
return staleProp != currProp ? currProp : '';
}
And then use it like:
let returnObj = {
firstName : getProp('firstName'),
lastName : getProp('lastName'),
email : getProp('email')
}
Running Example
var staleProfile = {
firstName: 'john',
lastName: 'smith',
email: 'js#gmail.com'
}
var CurrentCustomer = {};
CurrentCustomer.profile = {
firstName: 'paul',
lastName: 'smith',
email: 'js#yahoo.com'
}
function getProp(prop) {
let staleProp = staleProfile[prop];
let currProp = CurrentCustomer.profile[prop];
return staleProp != currProp ? currProp : '';
}
let returnObj = {
firstName: getProp('firstName'),
lastName: getProp('lastName'),
email: getProp('email')
}
console.log(returnObj);
The advantage of this helper function is that, in case you need to update your strategy for replacement of a missing value, you only have to do it in one place.
Furthermore, you could have an array of keys you would like to extract:
let keys = ['firstName', 'lastName', 'email'];
Or perhaps extract all using Object.keys:
let keys = Object.keys(staleProfile);
And then you can store the keys using the getProp function:
keys.forEach(k => {
returnObj[k] = getProp(k);
});
This would make adding/removing properties simply a matter of the current content the keys array. When you need to remove or add a property, you can either update the keys array in the first example, or update the staleProfile in the second example and let Object.keys return the values for you. Either way, with one small change you can add/remove properties.
Running example:
var staleProfile = {
firstName: 'john',
lastName: 'smith',
email: 'js#gmail.com'
}
var CurrentCustomer = {};
CurrentCustomer.profile = {
firstName: 'paul',
lastName: 'smith',
email: 'js#yahoo.com'
}
function getProp(prop) {
let staleProp = staleProfile[prop];
let currProp = CurrentCustomer.profile[prop];
return staleProp != currProp ? currProp : '';
}
let keys = Object.keys(staleProfile);
let returnObj = {};
keys.forEach(k => {
returnObj[k] = getProp(k);
});
console.log(returnObj);
Note: James Thorpe made a good observation in the comment.
what if one of the future properties you speak of could validly hold an empty string? In that case, you won't know if it's been updated to a an empty string or is unchanged. You may want to consider using null for unchanged items

Categories