I am trying to add a new object to existing object.
In my mobx Store I have an existing object which contains one user:
#observable user = {
id: 101,
email: 'kevin#dev.com',
personalInfo: {
name: 'kevin',
address: {
city: 'Costa Mesa',
state: 'CA'
}
}
}
I want to add another user to existing object:
id: 102,
email: 'john#dev.com',
personalInfo: {
name: 'john',
address: {
city: 'New York',
state: 'NY'
}
}
I want my final code to look like this:
#observable user = {
id: 101,
email: 'kevin#dev.com',
personalInfo: {
name: 'kevin',
address: {
city: 'Costa Mesa',
state: 'CA'
}
},
id: 102,
email: 'john#dev.com',
personalInfo: {
name: 'john',
address: {
city: 'New York',
state: 'NY'
}
}
}
What would be the correct format to add another object to the existing object?
Would this work?
updateObjectState (){
const user2 = {
id: 102,
email: 'john#dev.com',
personalInfo: {
name: 'john',
address: {
city: 'New York',
state: 'NY'
}
}
}
store.pressedDate = [...store.pressedDate, user2]
}
Thanks in advance!
Your desired result can't be achieved, as id is repeated so it will overwrite last id, wrap each user in object or use array
using id as key and placing values, when you want to add new user just create a new key value pair on user
#observable user = {
'101':{
id: 101,
email: 'kevin#dev.com',
personalInfo: {
name: 'kevin',
address: {
city: 'Costa Mesa',
state: 'CA'
}
}
}
}
Or having user as an array, to add new user just push the value in user
#observable user = [{
id: 101,
email: 'kevin#dev.com',
personalInfo: {
name: 'kevin',
address: {
city: 'Costa Mesa',
state: 'CA'
}
}
}]
P.S - I am not sure how you're using data, but i will go with the object way,
Related
My object looks like below structure. How can I remove the below mentioned three lines
data: [
{ id: 1, name: Mike, city: philps, state: New York, _id:'323232323'},
{ id: 2, name: Steve, city: Square, state: Chicago, _id:'32324444'},
{ id: 3, name: Jhon, city: market, state: New York, _id:'323277777'},
{id: '{"name":"test","email":""}',name: Jhon, city: market, state: New York} //need to remove this
{ id: 4, name: philps, city: booket, state: Texas, _id:'32328888'},
{ id: 5, name: smith, city: brookfield, state: Florida, _id:'32329999'},
{ id: 6, name: Broom, city: old street, state: Florida, _id:'3230000'},
{id: '{"name":"test","email":""}',name: Broom, city: old street, state: Florida} //need to remove this
{id: '{"name":"test","email":""}',name: smith, city: brookfield, state: Florida} //need to remove this
]
data = data.filter(item => item.id === '{"name":"test","email":""}');
Simple in one line
let data = [
{ id: 1, name: "A"},
{ id: 2, name: "B"},
{id: {"name":"test","email":""},name: "C"} //need to remove this
];
data = data.filter(item => Number.isInteger(item.id));
console.log(data);
I tried to solve the problem on my own but I did not manage to. So I decided to ask for help.
I've got an array of JSON objects like this:
const objArr = [
{
name: 'Andrew',
city: 'London'
},
{
name: 'Edouard',
city: 'Paris'
},
{
name: 'Nathalie',
city: 'London'
},
{
name: 'Patrick',
city: 'London'
},
{
name: 'Mathieu',
city: 'Paris'
}
];
I want to gather objects with same key value - in that case the city key - in a new array to obtain this:
const newObjArr = [
[{
name: 'Andrew',
city: 'London'
},
{
name: 'Nathalie',
city: 'London'
},
{
name: 'Patrick',
city: 'London'
}],
[{
name: 'Edouard',
city: 'Paris'
},
{
name: 'Mathieu',
city: 'Paris'
}]
];
This is a job for .reduce().
const objArr = [
{name: 'Andrew', city: 'London'},
{name: 'Edouard', city: 'Paris'},
{name: 'Nathalie', city: 'London'},
{name: 'Patrick', city: 'London'},
{name: 'Mathieu', city: 'Paris'}
];
// Object of arrays
const result = objArr.reduce((acc, obj) => {
return {...acc, [obj.city]: [...acc[obj.city] || [], obj]}
}, {})
// Array of arrays
const result2 = Object.values(result);
console.log(result2)
Use lodash group by and then add to new array
var objArr = [ { name: 'Andrew', city: 'London' }, { name: 'Edouard', city: 'Paris' }, { name: 'Nathalie', city: 'London' }, { name: 'Patrick', city: 'London' }, { name: 'Mathieu', city: 'Paris' } ]
var grouped = _.mapValues(_.groupBy(objArr, 'city'),
clist => clist.map(city => _.omit(city, 'city')));
var result=[]
for (const [key, value] of Object.entries(grouped)) {
var array=[]
value.forEach(x=>{
array.push({ name: x.name, city:key })
})
result.push(array);
}
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
You can use reduce to group by a field using that field as the key and then use Object.values if you really just want the values:
const objArr = [ { name: 'Andrew', city: 'London' }, { name: 'Edouard', city: 'Paris' }, { name: 'Nathalie', city: 'London' }, { name: 'Patrick', city: 'London' }, { name: 'Mathieu', city: 'Paris' } ];
var groupBy = function(array, k) {
return array.reduce(function(acc, cur) {
(acc[cur[k]] = acc[cur[k]] || []).push(cur);
return acc;
}, {});
};
console.log(Object.values(groupBy(objArr, 'city')));
I have an array of objects like this one:
[
{
name: 'John',
email: 'user#mail.com',
city: 'London',
type: 'CLIENT'
},
{
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
type: 'USER'
},
{
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
]
I need to transform it into something like this:
{
CLIENT: {
name: 'John',
email: 'user#mail.com',
city: 'London'
},
USER: {
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
},
ADMIN: {
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
}
What's the best approach?
Thank you
Use Array#reduce with a simple object destructuring to get your desired result:
const data = [{
name: 'John',
email: 'user#mail.com',
city: 'London',
type: 'CLIENT'
},
{
name: 'Steve',
email: 'stave#mail.com',
city: 'Rome',
type: 'USER'
},
{
name: 'Mark',
email: 'mark#mail.com',
city: 'Paris',
type: 'ADMIN'
}
];
const result = data.reduce((acc, { type, ...obj }) => {
acc[type] = obj;
return acc;
}, {})
console.log(result);
With upcoming object rest properties in ES2018/ES9 or with BABEL, you could take the type property and use the rest properties for a new object for assignment.
var array = [{ name: 'John', email: 'user#mail.com', city: 'London', type: 'CLIENT' }, { name: 'Steve', email: 'stave#mail.com', city: 'Rome', type: 'USER' }, { name: 'Mark', email: 'mark#mail.com', city: 'Paris', type: 'ADMIN' }],
object = Object.assign(...array.map(({ type, ...o }) => ({ [type]: o })));
console.log(object);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could also use reduce() and Object.assign() to get the required result.
DEMO
var arr = [{ name: 'John', email: 'user#mail.com', city: 'London', type: 'CLIENT' }, { name: 'Steve', email: 'stave#mail.com', city: 'Rome', type: 'USER' }, { name: 'Mark', email: 'mark#mail.com', city: 'Paris', type: 'ADMIN' }];
console.log(arr.reduce((r,{type,...rest})=>Object.assign(r,{[type]:rest}),{}));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I want to filter this data array into state and city array. How can I achieve this using lodash or any other better way rather than for loop and maintaining extra arrays.
data: [
{ id: 1, name: Mike, city: philps, state: New York},
{ id: 2, name: Steve, city: Square, state: Chicago},
{ id: 3, name: Jhon, city: market, state: New York},
{ id: 4, name: philps, city: booket, state: Texas},
{ id: 5, name: smith, city: brookfield, state: Florida},
{ id: 6, name: Broom, city: old street, state: Florida},
]
which user click state, list of state appears.
{state: New York, count: 2},
{state: Texas, count: 1},
{state: Florida, count: 2},
{state: Chicago, count: 1},
When user click particular state, list of cities of that state appears. For ex. when user clicks New York state,
{id:1, name: Mike, city: philps}
{id:3, name: Jhon, city: market}
You can do this using native javascript by applying filter method which accepts as parameter a callback provided function.
let data = [ { id: 1, name: 'Mike', city: 'philps', state:'New York'}, { id: 2, name: 'Steve', city: 'Square', state: 'Chicago'}, { id: 3, name: 'Jhon', city: 'market', state: 'New York'}, { id: 4, name: 'philps', city: 'booket', state: 'Texas'}, { id: 5, name: 'smith', city: 'brookfield', state: 'Florida'}, { id: 6, name: 'Broom', city: 'old street', state: 'Florida'}, ]
data = data.filter(function(item){
return item.state == 'New York';
}).map(function({id, name, city}){
return {id, name, city};
});
console.log(data);
Another approach is to use arrow functions.
let data = [ { id: 1, name: 'Mike', city: 'philps', state:'New York'}, { id: 2, name: 'Steve', city: 'Square', state: 'Chicago'}, { id: 3, name: 'Jhon', city: 'market', state: 'New York'}, { id: 4, name: 'philps', city: 'booket', state: 'Texas'}, { id: 5, name: 'smith', city: 'brookfield', state: 'Florida'}, { id: 6, name: 'Broom', city: 'old street', state: 'Florida'}, ]
data = data.filter((item) => item.state == 'New York').map(({id, name, city}) => ({id, name, city}));
console.log(data);
With lodash, you could use _.filter with an object as _.matches iteratee shorthand for filtering the object with a given key/value pair and
use _.countBy with _.map for getting a count of states.
var data = [{ id: 1, name: 'Mike', city: 'philps', state: 'New York' }, { id: 2, name: 'Steve', city: 'Square', state: 'Chicago' }, { id: 3, name: 'Jhon', city: 'market', state: 'New York' }, { id: 4, name: 'philps', city: 'booket', state: 'Texas' }, { id: 5, name: 'smith', city: 'brookfield', state: 'Florida' }, { id: 6, name: 'Broom', city: 'old street', state: 'Florida' }];
console.log(_.filter(data, { state: 'New York' }));
console.log(_
.chain(data)
.countBy('state')
.map((count, state) => ({ state, count }))
.value()
);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Simply Follow filter function
For Example
return data.filter(data => data.state == "New York" && count === 2);
This is fairly simple using Array.prototype.filter, Array.prototype.map, Array.prototype.reduce and destructuring:
//filter by particular state
const state = /*the given state*/;
const filtered = data
.filter(e => e.state == state)//filter to only keep elements from the same state
.map(e => {
const {id, name, city} = e;
return {id, name, city};
});//only keep the desired data ie id, name and city
//get states array
const states = data
.reduce((acc, elem) => {
const state_names = acc.map(e => e.state);//get all registered names
if(state_names.includes(elem.state)){//if it is already there
const index = acc.find(e => e.state==elem.state);
acc[index] = {state: acc[index].state, count: acc[index].count+1};//increment it's count
return acc;
}else//otherwise
return [...acc, {state: elem.state, count: 1}];//create it
}, []);
cf this jsfiddle to see it in action.
Let's assume I have a store with different orders. The orders have a delivery address and an invoice address. The address itself has a city, street etc.:
let data = [
{ id: 1, name: 'Anna', delivery: {city: "Amsterdam"}, invoice: {city: "Amsterdam"} },
{ id: 2, name: 'Anton', delivery: {city: "Amsterdam"}, invoice: {city: "Berlin"}}
];
I would like to filter all orders where the city of both the delivery address and the invoice address is the same.
I have tried that in a jsFiddle: https://jsfiddle.net/gbwv2bde/3/, but I am not so happy with the results. Does anybody know a way to use a Filter for that task?
Try this, it will return items Anna and Julie
var data = [
{ id: 1, name: 'Anna', delivery: { city: "Amsterdam" }, invoice: { city: "Amsterdam" } },
{ id: 2, name: 'Anton', delivery: { city: "Amsterdam" }, invoice: { city: "Berlin" } },
{ id: 3, name: 'John', delivery: { city: "Berlin" }, invoice: { city: "Paris" } },
{ id: 4, name: 'Julie', delivery: { city: "Paris" }, invoice: { city: "Paris" } }
];
var myStore = new Memory({ data: data, idProperty: 'id' });
var myResultsSet = myStore.filter(function (object) {
return object.delivery.city === object.invoice.city;
});
myResultsSet.forEach(function (item) {
console.log("item ", item.name);
});
Basically you can create a your own functions to pass to filter(), which you can use to write your own comparison logic.
See here for more details
https://github.com/SitePen/dstore/blob/master/docs/Collection.md
filter(query)
This filters the collection, returning a new subset collection. The
query can be an object, or a filter object, with the properties
defining the constraints on matching objects. Some stores, like server
or RQL stores, may accept string-based queries. Stores with in-memory
capabilities (like dstore/Memory) may accept a function for filtering
as well, but using the filter builder will ensure the greatest
cross-store compatibility.
EDIT: Example with more properties to compare. Your function just needs to return a true or false (true if the object matches your comparison conditions)
var data = [
{ id: 1, name: 'Anna', delivery: { city: "Amsterdam", price: 5 }, invoice: { city: "Amsterdam", price: 20 } },
{ id: 2, name: 'Anton', delivery: { city: "Amsterdam", price: 8 }, invoice: { city: "Berlin", price: 7 } },
{ id: 3, name: 'John', delivery: { city: "Berlin", price: 10 }, invoice: { city: "Paris", price: 20 } },
{ id: 4, name: 'Julie', delivery: { city: "Paris", price: 2 }, invoice: { city: "Paris", price: 3 } }
];
//example for custom filtering with nested properties
var myStore = new Memory({ data: data, idProperty: 'id' });
var myResultsSet = myStore.filter(function (object) {
if(object.delivery.city === object.invoice.city){
if (object.delivery.price < 5 && object.invoice.price < 5)
return true;
}else
return false;
});
myResultsSet.forEach(function (item) {
console.log("item ", item.name);
});