So say I have an array like so:
this.state = {
students: [{
"company": "This",
"firstName": "Randy",
"id": "1",
"lastName": "Orton",
},
{
"company": "That",
"firstName": "Clark",
"id": "2",
"lastName": "Kent",
}]
}
I would like to add an array to the first object so it looks like this.
this.state = {
students: [{
"company": "This",
"firstName": "Randy",
"id": "1",
"lastName": "Orton",
"array" : []
},
{
"company": "That",
"firstName": "Clark",
"id": "2",
"lastName": "Kent",
}]
}
How can I go about doing that without messing with initial state but only update it?
You can try to use these following ways:
this.state.students[0].array = [];
this.state.students.find(x => x.company === 'This').array = [];
After getting the response from server, you can add array property to each student object immediately:
Example:
var obj = {};
$.ajax({
type: 'POST',
url: '/yourAPIUrl'
}).done(function (response) {
obj.state = reponse;
for (var student of obj.state.students) {
student.array = [];
}
});
Related
I have an array of objects being returned to me as data, I'm looking to Create a new set of data, while retaining the old one for future use.
I'm trying to loop through the data given to create a new set of data that only contains age, but also removes any duplicates. I'm not too sure where to start with this.
data = [
{
"firstName": "John",
"lastName": "Doe",
"age": "99"
},
{
"firstName": "Jimmy",
"lastName": "Hendricks",
"age": "50"
},
{
"firstName": "William",
"lastName": "Shakespeare",
"age": "22"
},
{
"firstName": "Jane",
"lastName": "Eyre",
"age": "50"
}
]
What I'd like to end up with is something like this:
newData = [
{"age": "99"},
{"age": "50"},
{"age": "22"}
]
Or you can just use Set for eliminating duplicates:
// ages variable contain just the ages
const ages = data.map(person => person.age);
// new Set(ages) will remove duplicated values:
const newSet = Array.from(new Set(ages)).map(age => ({ age: age }));
Wow, so many approaches!
Here is another one, purely functional:
data = [ { "firstName": "John", "lastName": "Doe", "age": "99" }, { "firstName": "Jimmy", "lastName": "Hendricks", "age": "50" }, { "firstName": "William", "lastName": "Shakespeare", "age": "22" }, { "firstName": "Jane", "lastName": "Eyre", "age": "50" } ];
console.log(
Object.keys(data.reduce((obj,o)=>
(obj[o.age]=1,obj),{}))
.map(k=>({age:k}))
)
let newData = [];
let uniques = [];
data.forEach(el => {
if(!uniques.includes(el.age)){
newData.push({age: el.age});
uniques.push(el.age);
}
});
You can use .map and .filter combined with a Set for this:
const data = [
{
"firstName": "John",
"lastName": "Doe",
"age": "99"
},
{
"firstName": "Jimmy",
"lastName": "Hendricks",
"age": "50"
},
{
"firstName": "William",
"lastName": "Shakespeare",
"age": "22"
},
{
"firstName": "Jane",
"lastName": "Eyre",
"age": "50"
}
]
const newdata = data
.map(({age}) => ({age})) // convert `{age: <value of age>}`
.filter(function({age}) {
const isUnique = !this.has(age); //check if already present
this.add(age); //add anyway
return isUnique; //filter keeping uniques
}, new Set());//use a Set as the `this` context for the filter
console.log(newdata);
Here are two objects I need to compare and return specific values from object1 if found in object2.
object1 = {
"body": {
"items": [
{
"data": {
"name": "Smith",
"status": "Ready",
"userinfo": [
{
"dob": "01/01/2000",
"nickname": "Joe"
}
]
},
"workinfo": {
"company": "mycompany",
"address": "101 Main str."
}
},
{
"data": {
"name": "Luke",
"status": "Ready",
"userinfo": [
{
"dob": "01/01/2001",
"nickname": "LL"
}
]
},
"workinfo": {
"company": "mycompany",
"address": "101 Main str."
}
}
]
}
}
Object2 is even simple one:
object2 = {
"items": [
{
"name": "Smith",
"status": "Ready"
},
{
"name": "Luke",
"status": "Ready"
}
]
}
So if Object1 body.items[x].data.name found in Object2 items.name then finally I need to get new object like this:
object3 = {{name: "Smith", status: "Ready"}, {name: "Luke", status: "Ready"}}
You can use filter and find:
var obj1 = {
"body": {
"items": [{
"data": {
"name": "Smith",
"status": "Ready",
"userinfo": [{
"dob": "01/01/2000",
"nickname": "Joe"
}]
},
"workinfo": {
"company": "mycompany",
"address": "101 Main str."
}
},
{
"data": {
"name": "Luke",
"status": "Ready",
"userinfo": [{
"dob": "01/01/2001",
"nickname": "LL"
}]
},
"workinfo": {
"company": "mycompany",
"address": "101 Main str."
}
}
]
}
}
var obj2 = {
"items": [{
"name": "Smith",
"status": "Ready"
},
{
"name": "Luke",
"status": "Ready"
}
]
}
var output = obj2.items.filter(({name}) => obj1.body.items.find(({data}) => name === data.name))
console.log(output)
Filter will return all the objects that pass the find condition, that is, if the name is found in obj1
You can use _.intersectionWith() to return items from obj2, that their name equals data.name in obj2 items:
const obj1 = {"body":{"items":[{"data":{"name":"Smith","status":"Ready","userinfo":[{"dob":"01/01/2000","nickname":"Joe"}]},"workinfo":{"company":"mycompany","address":"101 Main str."}},{"data":{"name":"Luke","status":"Ready","userinfo":[{"dob":"01/01/2001","nickname":"LL"}]},"workinfo":{"company":"mycompany","address":"101 Main str."}}]}}
const obj2 = {"items":[{"name":"Smith","status":"Ready"},{"name":"Luke","status":"Ready"}]}
const result = _.intersectionWith(obj2.items, obj1.body.items,
(a, b) => _.get(a, 'name') === _.get(b, 'data.name')
)
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
With ES6 this is an easy task with Array.filter and Array.some:
const obj1 = {"body":{"items":[{"data":{"name":"Smith","status":"Ready","userinfo":[{"dob":"01/01/2000","nickname":"Joe"}]},"workinfo":{"company":"mycompany","address":"101 Main str."}},{"data":{"name":"Luke","status":"Ready","userinfo":[{"dob":"01/01/2001","nickname":"LL"}]},"workinfo":{"company":"mycompany","address":"101 Main str."}}]}}
const obj2 = {"items":[{"name":"Smith","status":"Ready"},{"name":"Luke","status":"Ready"}]}
const r = obj2.items.filter(x => obj1.body.items.some(y => y.data.name == x.name))
console.log(r)
Since you have the objects in the correct layout in obj2 you can start from there and filter them against obj1.
I need iterate specific objects in an object, and find the object with latter Date.
Here is example of my object:
var o = {
"data": [
{
"id": 2,
"category": "test1",
"parents": [
{
"id": 31,
"children": [
{
"firstName": "Steve",
"lastName": "Martin",
"created": "2018-04-06T22:00:00.000Z"
},
{
"firstName": "Steve2",
"lastName": "Martin2",
"created": "2016-02-10T23:00:00.000Z"
}
]
},
{
"id": 31,
"children": [
{
"firstName": "Julia",
"lastName": "Robbery",
"created": "2015-01-06T23:00:00.000Z"
},
{
"firstName": "Nikol",
"lastName": "Surachenko",
"created": "2017-04-06T22:00:00.000Z"
},
{
"firstName": "Nikol",
"lastName": "Surachenko",
"created": "2011-06-05T22:00:00.000Z"
}
]
}
]
}
]
}
I tried this:
var latter = null;
for (var i = 0; i < o.data[0].parents.length; i++) {
for (var j = 0; j < o.data[0].parents[i].children.length; j++) {
if (latter == null || moment(latter) < moment(o.data[0].parents[i].children[j].created))
latter=o.data[0].parents[i].children[j].created;
}
}
Can you tell me if exist some prettier way? For example with lambda, etc.?
Thanks in advice.
"pretty" is subjective, but in my opinion with lodash you could write it in a bit cleaner way:
mostRecent = _.max(
_.flatMap(
_.get(o, 'data.0.parents'),
'children'),
'created')
If lodash is not an option, you can roll out your own ad-hoc microframework:
let get = p => o => o[p];
let flatMap = (a, f) => [].concat(...a.map(f));
let max = (a, f) => a.map(x => [x, f(x)]).reduce((m, p) => m[1] > p[1] ? m : p)[0];
mostRecent = max(
flatMap(o.data[0].parents, get('children')),
get('created')
)
Using for-loops and compare dates.
This approach downstreams into the whole object to get the right object.
var o = { "data": [{ "id": 2, "category": "test1", "parents": [{ "id": 31, "children": [{ "firstName": "Steve", "lastName": "Martin", "created": "2018-04-06T22:00:00.000Z" }, { "firstName": "Steve2", "lastName": "Martin2", "created": "2016-02-10T23:00:00.000Z" } ] }, { "id": 31, "children": [{ "firstName": "Julia", "lastName": "Robbery", "created": "2015-01-06T23:00:00.000Z" }, { "firstName": "Nikol", "lastName": "Surachenko", "created": "2017-04-06T22:00:00.000Z" }, { "firstName": "Nikol", "lastName": "Surachenko", "created": "2011-06-05T22:00:00.000Z" } ] } ] }] }
var result = {};
for (var obj of o.data) {
for (var p of obj.parents) {
for (var c of p.children) {
result = !result.created || Date.parse(c.created) > Date.parse(result.created) ? c : result;
}
}
}
console.log(result);
You might do it a bit more functional:
const result = o.data[0].parents.reduce((res, {children}) => res.concat(children), [])
.reduce((old, curr) => Date(old.created) > Date(curr.created) ? old : curr);
My JSON is:
"people": [
{
"id": "1",
"firstName": "John",
"lastName": "Smith"
},
{
"id": "2",
"firstName": "Ashton",
"lastName": "Negus"
},
{
"id": "3",
"firstName": "Roy",
"lastName": "Murrey"
}
]
I want to find where an item is by given value.
E.g. if I ask for id 1, I will get 0 because it's the first item in the array. If I ask for id 2, I will get 1 because that's the second item in the array, and so on.
Any help appreciated!
Use findIndex
var idToSearch = "1";
var index = people.findIndex( s => s.id == idToSearch );
I'm not having any luck identifying an object defined in an array inside and array.
I have the following data
var values =
[
{
"letter": "S",
"clients": [
{
"_id": "58f61681e32f1927a41c19bf",
"firstName": "Shelly",
"lastName": "R",
}
]
},
{
"letter": "G",
"clients": [
{
"_id": "58f2ab99319e35299b1ee4a9",
"firstName": "Gary",
"lastName": "R",
}
]
}
]
and the following lodash call.
var identifier = '58f2ab99319e35299b1ee4a9';
var v = _.filter(values, {clients: [{_id: identifier}]});
which i read should work with nested arrays.
am i missing something here?
well i'm using this _.filter in a angular component routing scenario.
although values.clients object contains more information. i substituted that fiddle with the actual output and it worked. returned an instance. however code below does not.
}).state('clients.client', {
url: '/{clientId}',
component: 'client',
resolve: {
client : function(rolodex, $stateParams, _){
//var values = rolodex;
//console.log(JSON.stringify(values));
var identifier = $stateParams.clientId;
var v = _.filter(rolodex, {clients: [{_id: identifier}]});
console.log(v[0].clients[0]);
return v[0].clients[0];
}
}
});
G.
I guess i spoke to soon, this lodash script does not work correctly.
If i my secondary array contains more than one entry i get both entries in my result set.
[
{
"letter": "C",
"clients": [
{
"_id": "58f6b8a932edbb7dd718f05a",
"firstName": "Casie",
"lastName": "L"
},
{
"_id": "58f68b0d527cc336a8f86cc8",
"firstName": "Chad",
"lastName": "M"
}
]
},
{
"letter": "G",
"clients": [
{
"_id": "58f2ab99319e35299b1ee4a9",
"firstName": "Gary",
"lastName": "R"
}
]
},
{
"letter": "J",
"clients": [
{
"_id": "58f6b90032edbb7dd718f05c",
"firstName": "Jett",
"lastName": "F"
}
]
},
{
"letter": "S",
"clients": [
{
"_id": "58f61681e32f1927a41c19bf",
"firstName": "Shelly",
"lastName": "R"
},
{
"_id": "58f6b8d632edbb7dd718f05b",
"firstName": "Shirley",
"lastName": "A"
}
]
}
]
gives me the correct array containing the correct _id.
[
{
"letter": "S",
"clients": [
{
"_id": "58f61681e32f1927a41c19bf",
"firstName": "Shelly",
"lastName": "R"
},
{
"_id": "58f6b8d632edbb7dd718f05b",
"firstName": "Shirley",
"lastName": "A"
}
]
}
]
but i would like my result to look like this.
{
"_id": "58f61681e32f1927a41c19bf",
"firstName": "Shelly",
"lastName": "R"
}
this may be my answer.
var b = _(data).thru(function(col1){
return _.union(col1, _.map(col1, 'clients'));
})
.flatten()
.find({_id : '58f61681e32f1927a41c19bf'});
this approach seems to work for the mean time.
var b = _(data).thru(function(col1){
return _.union(col1, _.map(col1, 'clients'));
})
.flatten()
.find({_id : '58f61681e32f1927a41c19bf'});