I have a big array with below format
[
{
id: '1',
name: "bloh",
coordinates: [[51.3888562, 35.7474398], [51.388671,35.7470575],[51.3887346, 35.7470375]]
},
{
id: '2',
name: "blohbloh",
coordinates: [[51.3888562, 35.7474398],[51.3822271, 35.7444575]]
}
]
I want to convert format of coordinates property of all elements to below format
{
id: '1',
name: "bloh",
coordinates:[{longitude:51.3888562,latitude: 35.7474398},{longitude:51.3887346,latitude: 35.7470375}]
},
{
id: '2',
name: "blohbloh",
coordinates:[{longitude:51.3888562,latitude: 35.7474398},{longitude:51.3822271,latitude: 35.7444575}]
}
You should be able to do this with map:
let input = [{id: '1', name: "bloh", coordinates: [[51.3888562, 35.7474398], [51.388671,35.7470575],[51.3887346, 35.7470375]]},{id: '2', name: "blohbloh",coordinates: [[51.3888562, 35.7474398],[51.3822271, 35.7444575]]}];
let result = input.map(({id, name, coordinates}) => {
return { id, name, coordinates: coordinates.map(([latitude,longitude]) => { return { latitude, longitude}})};
});
console.log("Result: ", result);
You can loop through the array and then you need to use map to change representation of coordinates from array to object.
You can use following code to convert.
var arr=[{id: '1', name: "bloh", coordinates: [[51.3888562, 35.7474398], [51.388671,35.7470575],[51.3887346, 35.7470375]]},{id: '2', name: "blohbloh",coordinates: [ [51.3888562, 35.7474398],[51.3822271, 35.7444575]]}];
arr.forEach(elm=>elm.coordinates=elm.coordinates.map(c=>({longitude:c[0],latitude:c[1]})));
console.log(arr);
You can use two map() and destructuring to copy all properties of the top-level objects in a rest variable and map() the coordinates to another format:
const data = [{id: '1', name: "bloh", coordinates:[[51.3888562, 35.7474398], [51.388671,35.7470575],[51.3887346, 35.7470375]]},{id: '2', name: "blohbloh",coordinates:[[51.3888562, 35.7474398],[51.3822271, 35.7444575]]}];
const result = data.map(({ coordinates, ...rest }) =>
({
...rest,
coordinates: coordinates.map(([longitude, latitude]) => ({ longitude, latitude }))
})
);
console.log(result);
In any kind of problem you face, first, you should understand what you need to do, and prettier data will always help you to achieve this.
You want to convert this:
const original = [{
id: '1',
name: "bloh",
coordinates: [ [51.3888562, 35.7474398],
[51.388671,35.7470575],
[51.3887346, 35.7470375] ]
},
{
id: '2',
name: "blohbloh",
coordinates: [ [51.3888562, 35.7474398],
[51.3822271, 35.7444575] ]
}
]
To this:
{
id: '1',
name: "bloh",
coordinates:[
{longitude:51.3888562,latitude: 35.7474398},
{longitude:51.3887346,latitude: 35.7470375}
]
},
{
id: '2',
name: "blohbloh",
coordinates:[
{longitude:51.3888562,latitude: 35.7474398},
{longitude:51.3822271,latitude: 35.7444575}
]
}
We will use the 'for' loop because it is easier to see what's going on, in my own opinion.
for(i in original){
original[i].coordinates = original[i].coordinates.map(item => {return {
latitude: item[0],
longitude: item[1]}
})
}
console.log(JSON.stringify(original))
You can use prettifier to see your data in more pretty way,for example using this resource: https://jsonformatter.curiousconcept.com/
Hope this will help.
Related
I have an object which looks like this :
const data = {
students: [{
code: '1',
number: '22',
type: 'regular',
name: 'john',
age: '11',
class: 'A',
}, {
code: '2',
number: '23',
type: 'regular',
name: 'steve',
age: '12',
class: 'B',
}],
teachers: [{
code: '22',
number: '101',
type: 'intern',
name: 'mac',
}, {
code: '23',
number: '102',
type: 'perm',
name: 'jess',
}],
};
It has different keys and values.
Here, I am trying to massage this data so that I can obtain the following result: So I am trying to get an array which will have only students data and other which will have teachers data from one function itself.
const result1 = [{
code: '1',
number: '22',
type: 'regular',
name: 'john',
}, {
code: '2',
number: '23',
type: 'regular',
name: 'steve',
}];
const result2 = [{
code: '22',
number: '101',
type: 'intern',
name: 'mac',
}, {
code: '23',
number: '102',
type: 'perm',
name: 'jess',
}];
what I tried is :
const getData = ({data = []}) => {
data?.map({ code,
number,
regular,
name } ) => {
return{
code,
number,
regular,
name
}}
}
getData(data.students)
getData(data.teachers) // How do get this data in one function call itself
This gives me the result , but for this I need to call this function twice once for students and one for teachers. I want to call this function once.
Thanks
You could map new entries from the object and take the mapped new structure.
const
data = { students: [{ code: '1', number: '22', type: 'regular', name: 'john', age: '11', class: 'A' }, { code: '2', number: '23', type: 'regular', name: 'steve', age: '12', class: 'B' }], teachers: [{ code: '22', number: '101', type: 'intern', name: 'mac' }, { code: '23', number: '102', type: 'perm', name: 'jess' }] },
getData = ({ code, number, regular, name }) => ({ code, number, regular, name }),
result = Object.fromEntries(Object
.entries(data)
.map(([k, v]) => [k, v.map(getData)])
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Since from the provided data, it looks like the OP wants to mainly map a certain set of properties of student/teacher items from a map/object, a possible approach is to reduce the data object's entries and apply the mapping exclusively for a matching students or teachers key each referring to a valid array-type value.
const data = {
students: [{ code: "1", number: "22", type: "regular", name: "john", age: "11", class: "A" }, { code: "2", number: "23", type: "regular", name: "steve", age: "12", class: "B" }],
teachers: [{ code: "22", number: "101", type: "intern", name: "mac" }, { code: "23", number: "102", type: "perm", name: "jess" }],
};
const {
students: result1,
teachers: result2,
} = Object
.entries(data)
.reduce((result, [key, value]) => {
if (
// process only for a matching key ...
(/^students|teachers$/).test(key)
// ... and a valid value type.
&& Array.isArray(value)
) {
result[key] = value
.map(({ code, number, type, name }) =>
({ code, number, type, name })
);
}
return result
}, {});
console.log({ result1, result2 });
.as-console-wrapper { min-height: 100%!important; top: 0; }
I'm not sure what use there is in this, but since you want to run a function twice and get two results, do that, and combine into an object:
const data = {
students: [{
code: '1',
number: '22',
type: 'regular',
name: 'john',
age: '11',
class: 'A'
}, {
code: '2',
number: '23',
type: 'regular',
name: 'steve',
age: '12',
class: 'B'
}],
teachers: [{
code: '22',
number: '101',
type: 'intern',
name: 'mac'
}, {
code: '23',
number: '102',
type: 'perm',
name: 'jess'
}]
};
const transformData = (data = []) =>
data.map(({
code,
number,
regular,
name
}) => ({
code,
number,
regular,
name
}));
const getData = (data) =>
({
students: transformData(data.students),
teachers: transformData(data.teachers)
});
console.log(getData(data));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Note: I modified the transformData function to remove some extra syntax, and to remove the optional chaining since the Stack Snippets' ancient version of Babel doesn't support it.
Also, there's no property named regular on the original objects in the array, so they come out undefined.
Based on the input and output looks like you're just trying to slice off the keys age and class from the objects. So you'd just need to iterate through both the keys then the underlying objects to remove them.
const getData = (data) => {
Object.keys(data).forEach(function callback(key) {
let value = data[key];
value.forEach(function callback(obj) {
let blockArray = ['age', 'class'];
blockArray.forEach(e => delete obj[e]);
});
});
return data;
}
const updatedData = getData(data);
const result1 = updatedData.students;
console.dir(result1);
const result2 = updatedData.teachers;
console.dir(result2);
I've got array of objects, where I take only locations array. My goal is to merge these locations array to one array, however I fail to do so and get empty array. This is how I do it:
let results = [{
id: '1',
locations: ['aaaa', 'bbbbbb', 'cccccc']
},
{
id: '2',
locations: []
},
{
id: '3',
locations: ['ddd', 'aaadsad', 'sefd']
},
{
id: '4',
locations: ['ffff', 'eeee', 'sfdsfsd']
},
];
const locationIds = [].concat.apply([], ...results.filter(s => s.locations && s.locations.length > 0).map(({
locations
}) => ({
locations
})));
console.log(locationIds);
what I am doing wrong here? The result should be
['aaaa', 'bbbbbb', 'cccccc', 'ddd', 'aaadsad', 'sefd', 'ffff', 'eeee', 'sfdsfsd'];
You don't need filter here. Just use map method by passing a callback provided function which is applied for every item on the array.
let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }, ];
const locationIds = [].concat(...results.map(s => s.locations));
console.log(locationIds);
You can try with flatMap():
The flatMap() method first maps each element using a mapping function, then flattens the result into a new array. It is identical to a map() followed by a flat() of depth 1, but flatMap() is often quite useful, as merging both into one method is slightly more efficient.
let results = [{
id: '1',
locations: ['aaaa', 'bbbbbb', 'cccccc']
},
{
id: '2',
locations: []
},
{
id: '3',
locations: ['ddd', 'aaadsad', 'sefd']
},
{
id: '4',
locations: ['ffff', 'eeee', 'sfdsfsd']
},
];
const locationIds = results.flatMap(i => i.locations);
console.log(locationIds);
You could taka a Array#flatMap with the wanted property. If the property is not given, add a default array || [].
let results = [{ id: '1', locations: ['aaaa', 'bbbbbb', 'cccccc'] }, { id: '2', locations: [] }, { id: '3', locations: ['ddd', 'aaadsad', 'sefd'] }, { id: '4', locations: ['ffff', 'eeee', 'sfdsfsd'] }],
locationIds = results.flatMap(({ locations }) => locations);
console.log(locationIds);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Can also solve using the Reduce function from Array.prototype.
var newResults = results.reduce(function(acc, curr) {
return acc.concat(curr.locations)
},[]
)
hope this helps
I spent too long on this not to post my own solution - interesting puzzle for me, although the other answers are no doubt more performant and readable. It uses the same sort of strategy as your original post, which might help point out where it went wrong.
const locationIds = [].concat
.apply([], results.filter(result =>
result.locations && result.locations.length > 0)
.map(result => { return result.locations }));
I have an array of objects and array of strings
cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}]
userChoice = ['2','4']
I need to iterate over cities with userChoice and find name of cities by id.
I guess it's going to be a nested loop, but I am strugling with it.
cities.filter(city=> userChoice.forEach(choice => choice == city.id))
You can use filter() and includes() to filter cities array by checking if a city's id is present in userChoice array.
To get just the names, you can use map() to transform the result.
let cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}];
let userChoice = ['2','4'];
let filteredCities = cities.filter(city => userChoice.includes(city.id));
let names = filteredCities.map(city => city.name);
console.log(names);
You could use a Map object to look up ID based on city.
let cityMap = new Map(cities.map(c => [c.name, c.id]));
console.log(cityMap.get("Rome")); // --> "2"
Just use a simple map, you map the array element to the city from the other array. You might want to put a null check in if you can have values that might not be in the array but for simplicity I left it out.
const cities = [ { id: '1', name: 'Paris'}, { id: '2', name: 'Rome'}, { id: '3', name: 'London'}, { id: '4', name: 'Barcelona'}];
const userChoice = ['2','4'];
const userCities = userChoice.map(val => cities.find(c => c.id === val).name);
console.log(userCities)
I have an object where the number values for the user_id are strings but I want to change these to return as numbers, how can I do this?
const users =
[
{ user_id: '1', name: 'Jack'},
{ user_id: '2', name: 'Emma'},
{ user_id: '3', name: 'David'}
]
// I want the output to look like this
const users =
[
{ user_id: 1, name: 'Jack'},
{ user_id: 2, name: 'Emma'},
{ user_id: 3, name: 'David'}
]
Inplace
users.forEach(u=>u.user_id*=1)
const users =
[
{ user_id: '1', name: 'Jack'},
{ user_id: '2', name: 'Emma'},
{ user_id: '3', name: 'David'}
]
users.forEach(u=>u.user_id*=1)
console.log(users);
Use a simple map, and use the unary + operator to convert to numbers.
const users = [{
user_id: '1',
name: 'Jack'
},
{
user_id: '2',
name: 'Emma'
},
{
user_id: '3',
name: 'David'
}
];
const res = users.map(({ name, user_id }) => ({ name, user_id: +user_id }));
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
ES5 syntax:
var users = [{
user_id: '1',
name: 'Jack'
},
{
user_id: '2',
name: 'Emma'
},
{
user_id: '3',
name: 'David'
}
];
var res = users.map(function(user) {
return { name: user.name, user_id: +user.user_id };
});
console.log(res);
.as-console-wrapper { max-height: 100% !important; top: auto; }
return users.map(user => ({...user, user_id: +user.user_id}))
May be like:-
let users =
[
{ user_id: '1', name: 'Jack'},
{ user_id: '2', name: 'Emma'},
{ user_id: '3', name: 'David'}
];
users = users.map(a => {
a.user_id = +a.user_id;
return a;
});
console.log(users);
I know this question already has an answer, but I wanted to offer an alternative solution that you may find beneficial and I'll explain why.
Answer:
Instead of utilizing a typical transform on the users array, you can apply a Proxy to each object and utilize the get handler to test if a property's value is able to be coerced to a number by using the + operator. This is done using a short-circuit evaluation, which returns the first true expression. If a property's value cannot be turned into a number, it will return the original value with no coercion( in this case, a string ).
users = users.map(_ =>
new Proxy(_, {get: (target, property) => +target[property] || target[property]}))
Why is this useful?
Code will always rely on your use-case. In your question you asked how to convert user_id to a number within your users object. If this is a one-off situation where you only need this specific property to be coerced to a numeric value, applying a proxy to your objects would not be recommended.
however
If you find yourself in a situation where you have a number of property values that you would like converted to number types if possible, you may consider using the above technique so that you don't have to pinpoint and update each property name within a separate conversion function.
Note: Since we are using a map method to bundle our original objects with a Proxy handler,you would either need to use a different declarative (var or let), or use Array.from in your original users declaration:
const users = Array.from(
[
{ user_id: '1', name: 'Jack'},
{ user_id: '2', name: 'Emma'},
{ user_id: '3', name: 'David'}
], _ => new Proxy(_, {get: (target, property) => +target[property] || target[property]}));
Code Example:
let users =
[{
user_id: '1',
name: 'Jack'
},
{
user_id: '2',
name: 'Emma'
},
{
user_id: '3',
name: 'David'
}
];
users = users.map(_ => new Proxy(_, { get: (target, property) => +target[property] || target[property]}))
users.forEach(({user_id, name}) => (console.log("user id: " + user_id + " is type: " + typeof user_id), console.log("name: " + name + " is type: " + typeof name)));
I am trying to make a new array from the data object that I have which looks like this:
const data= {
periods: [{
month: 'January',
types: [
{
name: 'sick leave',
difference: '14',
revisioned: '7000',
paid: '5000',
},
{
name: 'holiday',
difference: '12',
revisioned: '4000',
paid: '6000',
},
],
received: '3000',
taken: '2000',
result: '0',
},
{
month: 'February',
types: [
{
name: 'sick leave',
difference: '5',
revisioned: '100',
paid: '200',
},
{
name: 'holiday',
difference: '4',
revisioned: '300',
paid: '232',
},
],
received: '-2000',
taken: '2000',
result: '0',
}],
};
What I would like to do is, to take that object and take the properties types, received, taken and result and from each of these properties values create an array that would be a property of an object in a new array. The end result of the new array would look something like this:
[
{
name: 'sick_leave_difference',
result: ['14', '5'],
},
{
name: 'sick_leave_revisioned',
result: ['7000', '100'],
},
{
name: 'sick_leave_paid',
resultat: '[5000, 200]',
},
{
name: 'holiday_difference',
resultat: ['12', '4'],
},
{
name: 'holiday_revisioned',
result: ['4000', '300'],
},
{
name: 'holiday_paid',
result: '[6000, 232]',
},
{
name: 'received',
resultat: ['3000', '-2000'],
},
{
navn: 'taken',
result: ['2000', '2000'],
},
{
name: 'result',
result: ['0', '0'],
},
];
The problem is that the propery types contains an array and it is different is different from the other properties, so I am not sure how to achieve this and also in an elegant way?
Use Array.reduce() to extract and flatten the types array. Reduce the flattened array, and iterate the each object's entries with Array.forEach(). Create the result object if it doesn't exists, and add the results. Extract back to array using Object.values():
const data= {"periods":[{"month":"January","types":[{"name":"sick leave","difference":"14","revisioned":"7000","paid":"5000"},{"name":"holiday","difference":"12","revisioned":"4000","paid":"6000"}],"received":"3000","taken":"2000","result":"0"},{"month":"February","types":[{"name":"sick leave","difference":"5","revisioned":"100","paid":"200"},{"name":"holiday","difference":"4","revisioned":"300","paid":"232"}],"received":"-2000","taken":"2000","result":"0"}]};
const result = Object.values(data.periods
.reduce((r, { types }) => [...r, ...types], [])
.reduce((r, { name, ...props }) => {
Object.entries(props).forEach(([k, v]) => {
const navn = `${name} ${k}`.replace(' ', '-');
if(!r[navn]) r[navn] = { navn, result: [] };
r[navn].result.push(v);
});
return r;
}, {}));
console.log(result);