I have my original objects as follow. All I need is to just extract few properties from existing one and create new object.
var data = [{
id: 3,
name: Axe,
location: alkt
}, {
id: 5,
name: Roy,
location: grelad
}]
I need my output as,
var data_new = [{
id: 3,
name: Axe
}, {
id: 5,
name: Roy,
}]
How to implement in underscore js or any simple method. Possible its a large JSON object.
If there are just few properties you want to extract then simple Array.prototype.map will works fine:
var data = [{
id: 3,
name: 'Axe',
location: 'alkt'
}, {
id: 5,
name: 'Roy',
location: 'grelad'
}]
var result = data.map(function(obj) {
return {
id: obj.id,
name: obj.name
};
});
alert(JSON.stringify(result, null, 4));
Use pick in undescorejs http://underscorejs.org/#pick
Or omit http://underscorejs.org/#omit
_.pick({name: 'moe', age: 50, userid: 'moe1'}, 'name', 'age');
=> {name: 'moe', age: 50}
_.pick({name: 'moe', age: 50, userid: 'moe1'}, function(value, key, object) {
return _.isNumber(value);
});
=> {age: 50}
It you want remove each item's location
var data_new = _.map(data, function(item) {
return _.omit(item, 'location');
});
If all you want is remove properties from objects in an array, you could just delete them while iterating with forEach:
var data_new = data;
data_new.forEach(function(obj){ delete obj.location; /* or any other */ });
$scope.data_new = [];
for(i in $scope.data){
$scope.data_new.push(
{ id: $scope.data[i].id, name: $scope.data[i].name }
)
}
Related
I have an array of object as below:
let arr = [{
id: 1,
name: 'John',
lastName: 'Smith'
},
{
id: 2,
name: 'Jill',
lastName: 'Smith'
}
];
I want to update an object with id = 1 with some properties from another object.
const obj = {
id: 1,
name: 'JOHn1'
}
The expected out is:
[{
id: 1,
name: 'JOHn1',
lastName: 'Smith'
},
{
id: 2,
name: 'Jill',
lastName: 'Smith'
}
]
I tried using Object.assign(), but it does not work. Could anyone please let me know.
arr = Object.assign(arr, obj);
thanks
thanks
You need to find the entry which you want to use as the assign target first: in this case, you need to query for the entry where id is 1. This can be done by using Array.prototype.find to locate the target, and then do Object.assign() on the target itself.
Since the found object is pass-by-reference, updating the object directly will update its entry in your array of objects directly.
See proof-of-concept below:
const arr = [{
id: 1,
name: 'John',
lastName: 'Smith'
},
{
id: 2,
name: 'Jill',
lastName: 'Smith'
}
];
const obj = {
id: 1,
name: 'JOHn1'
};
const foundObj = arr.find(({ id }) => id === obj.id);
if (foundObj) {
Object.assign(foundObj, obj);
}
console.log(arr);
This question already has answers here:
Aggregating object values of JavaScript arrays?
(2 answers)
Closed 4 years ago.
I have an Array of objects, for example:
[{
name: 'mike',
id: 3312,
points: 2,
summary: 'example',
}, {
name: 'andrew',
id: 4123,
points: 1,
summary: 'example',
}, {
name: 'mike',
id: 0522,
points: 5,
summary: 'example',
}]
I need to sum the points for each person, the problem I´m facing is there are more than 50 different person names so I can´t do something like this
for (let i = 0; i < issues.length; i++) {
if (issues[i].name == 'mike') {
//////////////////////
}
}
Because the API in future can return a new Person.
You can reduce into an object indexed by name:
const input = [{
name: 'mike',
id: 3312,
points: 2,
summary: 'example',
},
{
name: 'andrew',
id: 4123,
points: 1,
summary: 'example',
},
{
name: 'mike',
id: 0522,
points: 5,
summary: 'example',
}];
const points = input.reduce((a, { name, points }) => (
Object.assign(a, { [name]: (a[name] || 0) + points })
), {});
console.log(points);
If you do not want to use reduce and keep things simple you can still use a forEach loop as below:
const input = [{
name: 'mike',
id: 3312,
points: 2,
summary: 'example',
},
{
name: 'andrew',
id: 4123,
points: 1,
summary: 'example',
},
{
name: 'mike',
id: 0522,
points: 5,
summary: 'example',
}];
var res = {};
input.forEach((obj) => {
res[obj.name] = res[obj.name] ? res[obj.name]+obj.points : obj.points;
});
console.log(res);
I have a kids object that looks like the following:
const kids = {
name: 'john',
extra: {
city: 'London',
hobbies: [
{
id: 'football',
team: 'ABC',
},
{
id: 'basketball',
team: 'DEF',
},
],
},
};
and i have the following object that contains all sports and extra info for each.
const sports = [
{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
},
];
I want to get the list of all ids in the hobbies array and go through each of the sports items in the sports array, and found, add an extra field to that object available and give a value of true, so the result will look like:
const result = [
{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
available: true
},
];
by the way, here is my attempt:
const result = kids.extra.hobbies.map(a => a.id);
for (var key in sports) {
console.log(sports[key].name);
const foundIndex = result.indexOf(sports[key].name);
if ( foundIndex > -1) {
sports[key].available = true;
}
}
console.log(sports)
but this is too long... i am looking one liner looking code and robust logic.
This can be done many ways; however, an easy was is to divide the problem into two steps:
We can first flatten the kid's hobbies into an array by using the Array.map() function:
const hobbies = kids.extra.hobbies.map(hobby => hobby.id);
Then, we can iterate through the sports array and add an active property to any object which is present in the new hobbies array:
const result = sports.map(sport => {
if (hobbies.indexOf(sport.name) !== -1) {
sport.available = true;
}
return sport;
})
Complete Solution
const kids = {
name: 'john',
extra: {
city: 'London',
hobbies: [{
id: 'football',
team: 'ABC',
},
{
id: 'basketball',
team: 'DEF',
},
],
},
};
const sports = [{
name: 'volleyball',
coach: 'tom',
},
{
name: 'waterpolo',
coach: 'jack',
},
{
name: 'swimming',
coach: 'kate',
},
{
name: 'football',
coach: 'sara',
},
];
const hobbies = kids.extra.hobbies.map(hobby => hobby.id);
const result = sports.map(sport => {
if (hobbies.indexOf(sport.name) !== -1) {
sport.available = true;
}
return sport;
})
console.log(result);
Firstly, I would change my data structures to objects. Any time you have a list of things with unique ids, objects will make your life much easier than arrays. With that in mind, if you must use arrays, you could do the following:
const hobbies = kids.extra.hobbies
sports.forEach(s => s.available = hobbies.some(h => h.id === s.name))
Note that this mutates the original sports object (change to map for new), and also adds false/true instead of just true.
Build an array of the found sports first, then map while checking to see if the sports object's name is in it:
const kids = {name:'john',extra:{city:'London',hobbies:[{id:'football',team:'ABC',},{id:'basketball',team:'DEF',},],},}
const sports = [{name:'volleyball',coach:'tom',},{name:'waterpolo',coach:'jack',},{name:'swimming',coach:'kate',},{name:'football',coach:'sara',},];
const sportsInHobbies = kids.extra.hobbies.map(({ id }) => id);
const result = sports.map((sportObj) => {
const available = sportsInHobbies.includes(sportObj.name);
return available ? {...sportObj, available } : { ...sportObj };
});
console.log(result);
This is my json object:
{
id: 3,
cno: 103,
username: 'basha',
name: 'New Complaint',
desc: 'Need bag',
storeId: [ 5, 1 ]
}
I want my expected output like this:
[
{id: 3,cno: 103,username: 'basha',name: 'New Complaint',desc: 'Need bag',storeId:5},
{id: 3,cno: 103,username: 'basha',name: 'New Complaint',desc: 'Need bag',storeId:1}
]
You are right to choose .map. Issue is, you are trying to update an object and objects are passed using reference. So all the objects will hold same id. You will have to create a copy so that you do not override value. You can use Object.assign for that.
var data = {
id: 3,
cno: 103,
username: 'basha',
name: 'New Complaint',
desc: 'Need bag',
storeId: [ 5, 1 ]
};
var result = data.storeId.map(function(id){
return Object.assign({}, data, {storeId: id});
});
console.log(result)
If you are not comfortable using ES6 features, you can check following: How do I correctly clone a JavaScript object?
You can use .map() on the array storeId and return a new object which has current value as the value of storeId.
var obj = {
id: 3,
cno: 103,
username: 'basha',
name: 'New Complaint',
desc: 'Need bag',
storeId: [ 5, 1 ]
};
var data = obj.storeId.map(el => {
let newObject = Object.assign({}, obj);
newObject.storeId = el;
return newObject;
})
console.log(data);
You can use array#map with spread syntax to create an object with all the existing property and individual storeId.
var obj = {id: 3,cno: 103,username: 'basha',name: 'New Complaint',desc: 'Need bag',storeId: [ 5, 1 ]}
result = obj.storeId.map(storeId => ({...obj, storeId}) )
console.log(result);
var data = {
id: 3,
cno: 103,
username: 'basha',
name: 'New Complaint',
desc: 'Need bag',
storeId: [ 5, 1 ]
}
var finalData = data.storeId.map(x => {
return({
id: data.id,
cno: data.cno,
username: data.username,
name: data.name,
desc: data.desc,
storeId: x
})
});
console.log(finalData);
I tried this now i got this answer correctly, is this good approach?
I'm trying to take an array of objects and pick out the data that I only need. For example, below I only want the name, id, and users properties from the originalArray.
I figured out how to do it at the first level of iteration, but how do I do the same for the users array of objects? I only want to include the values in the allowedUserProps array found below.
https://jsfiddle.net/n8zw47cd/
Original Array
var originalArr = [
{
name: 'Obj 1',
id: 0,
something: 'else',
users: [{first_name: 'Joe', last_name: 'Smith'}]
},
{
name: 'Obj 2',
id: 1,
something: 'else',
users: [{first_name: 'Jane', last_name: 'Doe'}]
},
];
Desired Output
[
{
name: 'Obj 1',
id: 0,
users: [{first_name: 'Joe'}]
},
{
name: 'Obj 2',
id: 1,
users: [{first_name: 'Jane'}]
},
];
I'm using Underscore's pick method to return whitelisted values, but how can I change the users array of objects too?
function changeArray(arr) {
var allowedProps = ['name', 'id', 'users'];
var allowedUserProps = ['first_name'];
return _.map(arr, function(item) {
return _.pick(item, allowedProps);
});
}
var transformed = changeArray(originalArr);
Apply another map/pick to the sub-array:
function changeArray(arr) {
var allowedProps = ['name', 'id', 'users'];
var allowedUserProps = ['first_name'];
return _.map(arr, function(item) {
var out = _.pick(item, allowedProps);
out.users = _.map(out.users, function(usersItem) {
return _.pick(usersItem, allowedUserProps);
});
return out;
});
}
Same principle as for the outer array, but once for each sub-array element. This will give you the desired output.