JavaScript: Array + Object to Sorted Array - javascript

Have been stuck on this issue for 6+ hours. I have started to learn JavaScript few months ago, so far so good, but cant resolve this one.
const arrHeader["name","street","city","state","zip","phone","fax","custom"];
object as follows
const obj = {
zip: "01001"
phone: "77894644"
city: "Albany",
state: NY,
name: "John",
street: "123 Main St"
custom: "best user"
fax: ""
};
It is possible to get output as array (not associated array/object) sorted based on arrHeader? the lengh of array/object is the same. Please note blank for fax, the index in result should correspond to arrHeader, even if the value is null. Than you. Any suggestion are appreciated.
Output should look like for the given object. Not sure if " " best to keep index same.
var result["John","123 Main St","Albany","NY","01001","77894644"," ","best user"];
Thank you.

If I understand correctly, it seems like you want to perform a mapping operation on your array with .map(). This will allow you to take each element from arrHeader and map it to its value from your obj by using the element as a key obj[key]:
const arrHeader = ["name","street","city","state","zip","phone","fax","custom"];
const obj = { zip: "01001", phone: "77894644", city: "Albany", state: "NY", name: "John", street: "123 Main St", custom: "best user", fax: "" };
const res = arrHeader.map(key => obj[key]);
console.log(res);

Please find Array.reduce implementation of your requirement.
const arrHeader = ["name","street","city","state","zip","phone","fax","custom"];
const obj = {
zip: "01001",
phone: "77894644",
city: "Albany",
state: "NY",
name: "John",
street: "123 Main St",
custom: "best user",
fax: ""
};
const result = arrHeader.reduce((acc, curr) => {
acc.push(obj[curr]);
return acc;
}, []);
console.log(result);
Array.map implementation
const arrHeader = ["name","street","city","state","zip","phone","fax","custom"];
const obj = {
zip: "01001",
phone: "77894644",
city: "Albany",
state: "NY",
name: "John",
street: "123 Main St",
custom: "best user",
fax: ""
};
const result = arrHeader.map((node) => obj[node])
console.log(result);

Related

How can I sort the keys of the object of an array alphabetically? [duplicate]

This question already has answers here:
Sort JavaScript object by key
(37 answers)
Closed 3 months ago.
Suppose I have the following array:
var sample: [{
pin_code: "110015",
city: "New Delhi",
address: "xyz",
}]
I want the output as:
var sample: [{
address: "xyz",
city: "New Delhi",
pin_code: "110015",
}] // arranging the keys alphabetically
I wrote a function that gets the total keys and inserts it in a new object then returns the object if you don't understand anything let me know in the comments I'll explain!
var sample= [{
pin_code: "110015",
city: "New Delhi",
address: "xyz",
},{
pin_code: "110015",
city: "New Delhi",
address: "xyz",
}]
const sort_keys = (obj) =>{
const new_ordered_sample = []
const keys= []
obj.map((o,i) => {
keys[i] = [];
Object.keys(o).map((v, j)=>keys[i].push(v))
let newObj = {};
keys[i].sort().map((e)=>{
newObj[e] = obj[i][e]
})
new_ordered_sample.push(newObj)
})
return (new_ordered_sample)
}
sample = sort_keys(sample)
console.log(sample)
PS: Tested and working! you can edit the sample and add as many objects as you want!

How to transform set of fields inside an objects in javascript and react

I have a following object in React:
const userData =
{
id: 30,
firstName: "James",
lastName: "Anderson",
programmingLanguage: "Java, Python", # HERE
LanguageSpoken: "French, German, English", # HERE
Nationality: "French",
Hobby: "Developer, Hiking" # HERE
},
]
what would be the best way to loop through this object and transform the 3 fields programmingLanguage , LanguageSpoken and Hobby , which types are string into a List (type) of string.
so after the transformation, it should look like these.
const userData =
{
id: 30,
firstName: "James",
lastName: "Anderson",
programmingLanguage: ["Java", "Python"], # List of strings
LanguageSpoken: ["French", "German", "English"], # List of strings
Nationality: "French",
Hobby: ["Developer", "Hiking"] # List of strings
},
]
PS: (I know it suck) but the format above is the way i am receiving the data from the backend and because i am not allowed to change that i have to deal with it.
If it was for a single field I would have done this:
const transformedField = userData.programmingLanguage.toString().split(",");
const resultTransformedField = transformedField.map((i) => Number(i));
const newDataUser = {
...useData,
programmingLanguage: resultTransformedField,
};
but as mentioned above i have to modify 3 fields.
Thank you for the help.
I'd map each object to a new object with Object.fromEntries:
const properties = ['programmingLanguage', 'LanguageSpoken', 'Hobby'];
const userData = [
{
id: 30,
firstName: "James",
lastName: "Anderson",
programmingLanguage: "Java, Python",
LanguageSpoken: "French, German, English",
Nationality: "French",
Hobby: "Developer, Hiking"
},
];
const output = userData.map(
obj => Object.fromEntries(
Object.entries(obj).map(
([key, val]) => [key, properties.includes(key) ? val.split(', ') : val]
)
)
);
console.log(output);

In plain Javascript, trying to filter for multiple values in an array that contains User objects that contain other objects and arrays

thanks for taking a look at this. Sorry for length, trying to be clear!
WHAT I'M TRYING TO DO:
I have an array of users (each user an object) and am trying to filter the users on multiple criteria ("males from France" OR "females from Spain and United States with Engineering skills" etc) but it's proven beyond my skills so far.
The hard part has been that the users are objects within a User array, but within each user object, some values are additional objects or arrays. Here's what the user data array looks like (abbreviated):
let users = [
{
gender: 'male',
location: {street: 'Clement Street', country: 'United States'},
skills: ['engineering', 'underwater'],
}, ...
Notice gender is just a normal property/value but country is within a location object and skills are within an array.
I already have a search button interface that creates toggle buttons to search on each criteria available, and every time you click a button, I add or remove that criteria in a filter object. The filter object looks like this, and uses arrays inside it so that I can define multiple criteria at once, like multiple countries to search, multiple skills, etc.:
filter: {
gender: ['female'],
location: {
country: ['Spain'],},
skills: ['optics', ]
},
WHERE I REALLY GET STUCK
I've created a filterData method that can successfully filter based on Gender (male or female) but can't get it to ALSO filter on country (within the location object) or skills (within the skills array). My current filterData method only goes through one iteration per user, but I've tried For loops and forEach to try to go through each of the filter's criteria ('Spain', 'Optics'), but it just doesn't work. I only get gender.
I think I have two problems: 1) somehow conveying in the code that the item 'key' in some cases will not be a value, but an object or array that must also be searched within, and 2) creating some kind of looping behavior that will go through each of the filter criteria, instead of stopping after the first one (gender).
That's apparently over my head right now, so any guidance or suggestions would be appreciated, thanks very much! And here's all the code I've been working with, including my filterData method.
var filtering = {
filter: {
gender: ["female"],
location: {
country: ["Spain"],
},
skills: ["optics"],
},
users: [
{
gender: "male",
name: "John",
location: { street: "Clement Street", country: "United States" },
skills: ["engineering", "underwater"],
},
{
gender: "female",
name: "Mary",
location: { street: "5th Avenue", country: "Spain" },
skills: ["confidence", "optics"],
},
{
gender: "male",
name: "David",
location: { street: "Vermont Ave", country: "France" },
skills: ["cards", "metalurgy", "confidence"],
},
{
gender: "female",
name: "Rachel",
location: { street: "Vermont Ave", country: "France" },
skills: ["disguise", "electrical"],
},
{
gender: "female",
name: "Muriel",
location: { street: "Vermont Ave", country: "Germany" },
skills: ["flight", "surveillance"],
},
],
filterData: (filter) => {
const filteredData = filtering.users.filter((item) => {
for (let key in filter) {
if (!filter[key].includes(item[key])) {
return false;
}
return true;
}
});
console.log(filteredData);
},
};
filtering.filterData(filtering.filter);
There's a nifty trick called recursion, which is a function calling itself.
The updated code are: checkUserand
filterData
var filtering = {
filter: {
gender: ["female"],
location: {
country: ["Spain"],
},
skills: ["optics"],
},
users: [
{
gender: "male",
name: "John",
location: { street: "Clement Street", country: "United States" },
skills: ["engineering", "underwater"],
},
{
gender: "female",
name: "Mary",
location: { street: "5th Avenue", country: "Spain" },
skills: ["confidence", "optics"],
},
{
gender: "male",
name: "David",
location: { street: "Vermont Ave", country: "France" },
skills: ["cards", "metalurgy", "confidence"],
},
{
gender: "female",
name: "Rachel",
location: { street: "Vermont Ave", country: "France" },
skills: ["disguise", "electrical"],
},
{
gender: "female",
name: "Muriel",
location: { street: "Vermont Ave", country: "Germany" },
skills: ["flight", "surveillance"],
},
],
checkUser (filter, to_check) {
if (Array.isArray(filter))
{
return Array.isArray(to_check)
? filter.some(val => to_check.includes(val)) // if what we're checking is an array
: filter.includes(to_check); // otherwise it's a singular value
}
else
{
const all_checks = []; // this is to save every return value from the recursive function
for (let key in filter) // going through each key in the filter
{
const checked = this.checkUser(filter[key], to_check[key]) // passing two values, which will be compared with each other
all_checks.push(checked) // pushing the checked result
}
return all_checks.every(val => val) // checking that it passes the filter by ensuring every value is true
}
},
filterData () {
let filter = this.filter
return this.users.filter(user => this.checkUser(filter, user))
},
};
// filtering.filterData(filtering.filter);
// filtering.checkUser(filtering.filter, filtering.users[0])
const result = filtering.filterData()
console.log(result)
Bit complex data structure, you should clean. However, solved what expected.
const mergeFilter = (item, [key, value]) => {
let val = Array.isArray(item[key]) ? item[key] : [item[key]];
let m = value[0];
if (typeof value === "object" && !Array.isArray(value)) {
const k2 = Object.keys(value);
val = item[key][k2];
m = value[k2][0];
}
return val.includes(m);
};
const filterData = (users, filter) => {
const filters = Object.entries(filter);
const result = users.reduce((arr, item) => {
let found = filters.every(mergeFilter.bind(null, item));
if (found) arr.push(item);
return arr;
}, []);
return result;
};
var filtering = {"filter":{"gender":["female"],"location":{"country":["Spain"]},"skills":["optics"]},"users":[{"gender":"male","name":"John","location":{"street":"Clement Street","country":"United States"},"skills":["engineering","underwater"]},{"gender":"female","name":"Mary","location":{"street":"5th Avenue","country":"Spain"},"skills":["confidence","optics"]},{"gender":"male","name":"David","location":{"street":"Vermont Ave","country":"France"},"skills":["cards","metalurgy","confidence"]},{"gender":"female","name":"Rachel","location":{"street":"Vermont Ave","country":"France"},"skills":["disguise","electrical"]},{"gender":"female","name":"Muriel","location":{"street":"Vermont Ave","country":"Germany"},"skills":["flight","surveillance"]}]}
const result = filterData(filtering.users, filtering.filter);
console.log(result)

Sorting an array of objects with lodash: not working

I have an array that looks like this one (it has more objects, but the structure is the same):
[
{
especiality: "surgery",
users: [
{
id: "182",
country: "Colombia",
province: "Bogota",
telephone: "211112212",
neighbourhood: "La Santa"
region: "South",
},
{
id: "182",
country: "Venezuela",
province: "Caracas",
telephone: "322323333",
region: "North",
},
{
id: "183",
country: "Brasil",
telephone: "23232333",
neighbourhood: "Santos"
region: "South",
},
]
},
I want the addresses, if the ID is the same, to compose one single array (I need to map these elements). The outlook should look like this one:
user: [{id: 182, locations[(if they exist)
country: "Colombia",
province: "Bogota",
telephone: "211112212",
neighbourhood: "La Santa"
region: "South"], [country: "Venezuela",
province: "Caracas",
telephone: "322323333",
region: "North"],}]
I´m currently trying this, but it´s not working at all:
getGroups = test => {
_.chain(test)
.groupBy("id")
.toPairs()
.map(item => _.zipObject(["id", "country", "province", "neighbourhood", "region"], item))
.value();
return test
}
What am I doing wrong and how can I account for values that may not be available in all objects?
After grouping the items by the id, map the groups, and create an object with the id, and the items of the group as locations. Map the locations, and use _.omit() to remove the id from them.
I'm not sure about how you want to handle the outer array. I've used _.flatMap() to get a single array of users, but there's a commented option if you need to maintain the original structure.
getGroups = test =>
_(test)
.groupBy("id")
.map((locations, id) => ({
id,
locations: _.map(locations, l => _.omit(l, 'id'))
}))
.value();
const data = [{"especiality":"surgery","users":[{"id":"182","country":"Colombia","province":"Bogota","telephone":"211112212","neighbourhood":"La Santa","region":"South"},{"id":"182","country":"Venezuela","province":"Caracas","telephone":"322323333","region":"North"},{"id":"183","country":"Brasil","telephone":"23232333","neighbourhood":"Santos","region":"South"}]}];
const result = _.flatMap(data, ({ users }) => getGroups(users));
/** maintains the original structure
const result = _.map(data, ({ users, ...rest }) => ({
...rest,
users: getGroups(users)
}));
**/
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>

Better way to check if array element exists in JS object? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I have feature in my application that should allow users to select items in drop down menu and move them up and down. Once they select and click on the button I have to loop over the array of objects and pull only records that were selected in drop down menu. Here is example of my code:
var selectedColumns = ['first','last','city'];
var data = [
{
first: "Mike",
last: "Ross",
dob: "05/26/1978",
city: "Washington DC",
state: "DC",
zip: 22904
},
{
first: "John",
last: "Henderson",
dob: "11/06/1988",
city: "Iowa City",
state: "IA",
zip: 52401
},
{
first: "Nina",
last: "Barkley",
dob: "01/16/1968",
city: "New York",
state: "NY",
zip: 11308
},
{
first: "Jessie",
last: "Kuch",
dob: "02/02/1956",
city: "Des Moines",
state: "IA",
zip: 55432
},
{
first: "Jenny",
last: "Terry",
dob: "012/28/1988",
city: "Miami",
state: "FL",
zip: 83943
}
]
In selected column we only have first, last and city. Then I have to loop over data and pull only selected columns. One way to do that is like this:
for(var key in data){
for(var i=0; i<selectedColumns.lenght; i++){
var columnID = String(columns[i]);
console.log($.trim(data[key][columnID]));
}
}
While this solution works just fine, I'm wondering if there is better way to avoid inner loop and improve efficiency? I use JQuery/JavaScript in my project. If anyone knows a better way to approach this problem please let me know. Thank you.
You can use Array.map, Array.reduce and Object.assign
var selectedColumns = ['first','last','city'];
var data = [{first: "Mike",last: "Ross",dob: "05/26/1978",city: "Washington DC",state: "DC",zip: 22904},{first: "John",last: "Henderson",dob: "11/06/1988",city: "Iowa City",state: "IA",zip: 52401},{first: "Nina",last: "Barkley",dob: "01/16/1968",city: "New York",state: "NY",zip: 11308},{first: "Jessie",last: "Kuch",dob: "02/02/1956",city: "Des Moines",state: "IA",zip: 55432},{first: "Jenny",last: "Terry",dob: "012/28/1988",city: "Miami",state: "FL",zip: 83943}];
let result = data.map(o => selectedColumns.reduce((a,c) => Object.assign(a,{[c]:o[c]}), {}));
console.log(result);
EDIT
var selectedColumns = ['dob','last','city'];
var data = [{first: "Mike",last: "Ross",dob: "01/01/1900",city: "Washington DC",state: "DC",zip: 22904},{first: "John",last: "Henderson",dob: "11/06/1988",city: "Iowa City",state: "IA",zip: 52401},{first: "Nina",last: "Barkley",dob: "01/16/1968",city: "New York",state: "NY",zip: 11308},{first: "Jessie",last: "Kuch",dob: "02/02/1956",city: "Des Moines",state: "IA",zip: 55432},{first: "Jenny",last: "Terry",dob: "012/28/1988",city: "Miami",state: "FL",zip: 83943}];
let result = data.map(o => selectedColumns.reduce((a,c) => {
if(c === 'dob' && o[c] === '01/01/1900') a[c] = 'N/A';
else a[c] = o[c];
return a;
}, {}));
console.log(result);
Another important thing to mention is that it's generally a bad idea to use for ... in construct to iterate over array items in JavaScript (see Why is using "for...in" with array iteration a bad idea? for some explanations).
Just a single line of code by mapping the wanted properties.
Array#map for getting a new array of data and for mapping the wanted keys as new objects witk
computed property names and the value, assigned to a single object with
Object.assign and
spread syntax ... for taking an array as arguments.
var selectedColumns = ['first','last','city'],
data = [{ first: "Mike", last: "Ross", dob: "05/26/1978", city: "Washington DC", state: "DC", zip: 22904 }, { first: "John", last: "Henderson", dob: "11/06/1988", city: "Iowa City", state: "IA", zip: 52401 }, { first: "Nina", last: "Barkley", dob: "01/16/1968", city: "New York", state: "NY", zip: 11308 }, { first: "Jessie", last: "Kuch", dob: "02/02/1956", city: "Des Moines", state: "IA", zip: 55432 }, { first: "Jenny", last: "Terry", dob: "012/28/1988", city: "Miami", state: "FL", zip: 83943 }],
result = data.map(o => Object.assign(...selectedColumns.map(k => ({ [k]: o[k] }))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You will find Array.filter suits this use-case
var words = ['spray', 'limit', 'elite', 'exuberant', 'destruction', 'present'];
const result = words.filter(word => {
return word.length > 6;
});
console.log(result);
// expected output: Array ["exuberant", "destruction", "present"]
You could look into using filters where you build the filtering method based on the search criteria and return the filtered array.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
const newArr = oldArr.filter(record => record.first === 'Nina')
//newArr would only have Nina's record
alternatively if you are trying to go by having a particular field you can still use filter as well
var newArr2 = data.filter(record => record.hasOwnProperty('first'))
// newArr2 would have all records with the property name

Categories