Related
When I click the button, I want to include all the objects in the itemSold and itemGet objects of the customers into the products array. how can I do that?
let customers = [{
active: true,
id: 1,
product: {
itemSold: [{id:1,name : 'car'}, {id:2,name : 'home'}],
itemGet: [{id:3,name : 'phone'}, {id:4,name : 'fly'}],
},
},
{
active: true,
id: 2,
product: {
itemSold: [{id:5,name : 'lamb'}, {id:6,name : 'mouse'}],
itemGet: [{id:7,name : 'mouse pad'}, {id:8,name : 'tv'}],
},
},
];
let clickButton = document.querySelector("#clickButton");
let products = [];
clickButton.addEventListener("click", getProcuts()});
function getProducts(){}
<button id="clickButton" >Click
</button>
let customers = [{
active: true,
id: 1,
product: {
itemSold: [{ id: 1, name: 'car' }, { id: 2, name: 'home' }],
itemGet: [{ id: 3, name: 'phone' }, { id: 4, name: 'fly' }],
},
},
{
active: true,
id: 2,
product: {
itemSold: [{ id: 5, name: 'lamb' }, { id: 6, name: 'mouse' }],
itemGet: [{ id: 7, name: 'mouse pad' }, { id: 8, name: 'tv' }],
},
},
];
let clickButton = document.querySelector("#clickButton");
let products = [];
clickButton.addEventListener("click", getProducts);
function getProducts() {
for (let i = 0; i < customers.length; i++) {
products.push(...customers[i].product.itemGet, ...customers[i].product.itemSold);
}
console.log(products);
}
<button id="clickButton">Click</button>
We loop our customers array and then select product property there we push both itemSold and itemGet arrays into products.
You can map over the customers and concatenate the arrays.
const customers = [
{
active: true,
id: 1,
product: {
itemSold: [
{ id: 1, name: "car" },
{ id: 2, name: "home" },
],
itemGet: [
{ id: 3, name: "phone" },
{ id: 4, name: "fly" },
],
},
},
{
active: true,
id: 2,
product: {
itemSold: [
{ id: 5, name: "lamb" },
{ id: 6, name: "mouse" },
],
itemGet: [
{ id: 7, name: "mouse pad" },
{ id: 8, name: "tv" },
],
},
},
];
const products = customers.map((customer) => {
return customer.product.itemSold.concat(customer.product.itemGet);
});
console.log(products);
const customers = [
{
active: true,
id: 1,
product: {
itemSold: [
{ id: 1, name: "car" },
{ id: 2, name: "home" },
],
itemGet: [
{ id: 3, name: "phone" },
{ id: 4, name: "fly" },
],
},
},
{
active: true,
id: 2,
product: {
itemSold: [
{ id: 5, name: "lamb" },
{ id: 6, name: "mouse" },
],
itemGet: [
{ id: 7, name: "mouse pad" },
{ id: 8, name: "tv" },
],
},
},
];
const products = customers.map((customer) => {
return customer.product.itemSold.concat(customer.product.itemGet).flat();
});
console.log(products.flat());
I have an array of Javascript objects like below.
[
{
email: 'alex#test.com',
fn: 'Alex',
sn: 'McPherson',
phone: '01233xxxxx',
hours: '40',
rate: '20',
amount: '200',
vat: '60',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '2345',
area: 'uhj'
}
]
}
},
{
email: 'mike#test.com',
fn: 'Mike',
sn: 'Mann',
phone: '01233xxxxx',
hours: '50',
rate: '70',
amount: '500',
vat: '90',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '3456',
area: 'uio'
}
]
}
},
{
email: 'fred#test.com',
fn: 'Fred',
sn: 'Frogg',
phone: '01233xxxxx',
hours: '80',
rate: '90',
amount: '800',
vat: '100',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '4567',
area: 'asdaf'
},
{
id: '3456',
area: 'uio'
}
]
}
},
{
email: 'alex#test.com',
fn: 'Alex',
sn: 'McPherson',
phone: '01233xxxxx',
hours: '90',
rate: '30',
amount: '900',
vat: '120',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '4567',
area: 'asdaf'
},
{
id: '5678',
area: 'asdf'
}
]
}
}
]
What I ideally want is to group those of the same value (shipping.addresses.id) into there own sub array of objects. Expected outcome.
[
{
id: '1234',
area: 'xzy',
data: [
{
email: 'alex#test.com',
fn: 'Alex',
sn: 'McPherson',
phone: '01233xxxxx',
hours: '40',
rate: '20',
amount: '200',
vat: '60',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '2345',
area: 'uhj'
}
]
}
},
{
email: 'mike#test.com',
fn: 'Mike',
sn: 'Mann',
phone: '01233xxxxx',
hours: '50',
rate: '70',
amount: '500',
vat: '90',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '3456',
area: 'uhj'
}
]
}
}
]
},
{
id: '2345',
area: 'uhj',
data: [
{
email: 'alex#test.com',
fn: 'Alex',
sn: 'McPherson',
phone: '01233xxxxx',
hours: '40',
rate: '20',
amount: '200',
vat: '60',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '2345',
area: 'uio'
}
]
}
}
]
},
{
id: '3456',
area: 'uio',
data: [
{
email: 'mike#test.com',
fn: 'Mike',
sn: 'Mann',
phone: '01233xxxxx',
hours: '50',
rate: '70',
amount: '500',
vat: '90',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '1234',
area: 'xzy'
},
{
id: '3456',
area: 'uio'
}
]
}
},
{
email: 'fred#test.com',
fn: 'Fred',
sn: 'Frogg',
phone: '01233xxxxx',
hours: '80',
rate: '90',
amount: '800',
vat: '100',
agency: 'test',
start: '08/06/2017',
end: '10/06/2017',
shipping: {
addresses: [
{
id: '4567',
area: 'asdaf'
},
{
id: '3456',
area: 'uio'
}
]
}
}
]
}
]
I can group the input array using a specific attribute using particular key (code below) but I can't seem to get my head around resorting the array based on a key which is array in itself.
Array.from(
data.reduce(
(acc, o) => (acc.get(o.email).push(o), acc),
new Map(data.map( o => [o.email, []] ))
), ([key, value]) => value
)
You can reduce the data array into an object using shipping.addresses.id as keys and return an array using Object.values(). You will need to iterate over the addresses array of each object and create an entry for each id as they are encountered and push to these entries for subsequent elements with the same id.
const byAddressId = Object.values(
data.reduce((a, o) => {
o.shipping.addresses.forEach(({id, area}) => {
a[id] = {...a[id] ?? {id: id, area: area, data: []}};
a[id]['data'].push({...o});
});
return a;
}, {}));
const data = [{"email": "alex#test.com","fn": "Alex","sn": "McPherson","phone": "01233xxxxx","hours": "40","rate": "20","amount": "200","vat": "60","agency": "test","start": "08/06/2017","end": "10/06/2017","shipping": { "addresses": [ { "id": "1234", "area": "xzy" }, { "id": "2345", "area": "uhj" } ]}},{"email": "mike#test.com","fn": "Mike","sn": "Mann","phone": "01233xxxxx","hours": "50","rate": "70","amount": "500","vat": "90","agency": "test","start": "08/06/2017","end": "10/06/2017","shipping": { "addresses": [ { "id": "1234", "area": "xzy" }, { "id": "3456", "area": "uio" } ]}},{"email": "fred#test.com","fn": "Fred","sn": "Frogg","phone": "01233xxxxx","hours": "80","rate": "90","amount": "800","vat": "100","agency": "test","start": "08/06/2017","end": "10/06/2017","shipping": { "addresses": [ { "id": "4567", "area": "asdaf" }, { "id": "3456", "area": "uio" } ]}},{"email": "alex#test.com","fn": "Alex","sn": "McPherson","phone": "01233xxxxx","hours": "90","rate": "30","amount": "900","vat": "120","agency": "test","start": "08/06/2017","end": "10/06/2017","shipping": { "addresses": [ { "id": "4567", "area": "asdaf" }, { "id": "5678", "area": "asdf" } ]}}];
// return array of Object.values from the accumulator
const byAddressId = Object.values(
// reduce the data array into an object with shipping.addresses.id as keys
data.reduce((a, o) => {
// iterate over all addresses for each element
o.shipping.addresses.forEach(({id, area}) => {
// check if an id entry exists, otherwise create one
a[id] = {...a[id] ?? {id: id, area: area, data: []}};
// push the object to the data array of the id object
a[id]['data'].push({...o});
});
return a;
}, {}));
console.log(byAddressId);
That being said, you can use this same method to save yourself two map() calls compared to the group by email example you included in your question.
const byEmail = Object.values(
data.reduce((a, o) => (a[o.email] = [...a[o.email] ?? [], {...o}], a), {}));
I have an array of Objects named results and have the Object which key is the key value of editKeyValues object and value needs to be add in edit key. Below is the Input
var result = [{
name : 'database',
checked : true,
key : 1,
schemas : [
{
name : "schema2",
checked : true,
key : 6,
tables : [
{
name : "table2",
checked : true,
key : 7,
columns : [
{
name : "column1",
checked : true,
key : 8,
}
]
},
]
},
]
}]
var editKeyValues = { 8 : "column4", 6 : "schema4"}
Output that i want in a below format
var result = [{
name : 'database',
checked : true,
key : 1,
schemas : [
{
name : "schema2",
checked : true,
key : 6,
edit : "schema4"
tables : [
{
name : "table2",
checked : true,
key : 7,
columns : [
{
name : "column1",
checked : true,
key : 8,
edit : "column4" // value of key 8 from editkeyValues array
}
]
},
]
},]}]
Provide me a best approach because there is large amount of data in results Object... Is recursion a good idea ??? Help me to find out the best approach.
let data = [{
name: 'database',
checked: true,
key: 1,
schemas: [
{
name: "schema2",
checked: true,
key: 6,
tables: [
{
name: "table2",
checked: true,
key: 7,
columns: [
{
name: "column1",
checked: true,
key: 8,
}
]
},
]
},
]
}];
let schemas = data.flatMap(d => d.schemas);
let tables = schemas.flatMap(s => s.tables);
let columns = tables.flatMap(t => t.columns);
let flatData = [data, schemas, tables, columns].flat();
let editKeyValues = {8: "column4", 6: "schema4"};
Object.entries(editKeyValues).forEach(([key, newName]) =>
flatData.find(obj => obj.key === parseInt(key)).edit = newName);
console.log(data);
const data = [
{
id: 13,
product_name: 'Onion Pizza',
image: '26238.jpg',
category: {
id: 1,
name: 'Restaurants',
image: 'restaurant.png',
created_at: '2022-02-02T07:59:05.000000Z',
updated_at: '2022-02-15T10:58:49.000000Z',
},
status: '1',
created_at: '2022-02-19T12:22:09.000000Z',
updated_at: '2022-03-02T09:43:53.000000Z',
add_in_cart: false,
quantity_in_cart: 0,
add_in_wishlist: false,
variant: [
{
id: 34,
price: 140,
quantity: 10,
weight: '7 inch',
discount: 20,
product_id: 13,
created_at: '2022-03-02T12:46:06.000000Z',
updated_at: '2022-03-02T12:46:06.000000Z',
},
{
id: 35,
price: 350,
quantity: 5,
weight: '14 inch',
discount: 20,
product_id: 13,
created_at: '2022-03-02T12:46:06.000000Z',
updated_at: '2022-03-02T12:46:06.000000Z',
},
],
},
{
id: 15,
product_name: 'Veg Fresh Pizza',
image: '816404.jpg',
category: {
id: 1,
name: 'Restaurants',
image: 'restaurant.png',
created_at: '2022-02-02T07:59:05.000000Z',
updated_at: '2022-02-15T10:58:49.000000Z',
},
status: '1',
created_at: '2022-03-01T12:40:15.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
add_in_cart: false,
quantity_in_cart: 0,
add_in_wishlist: false,
variant: [
{
id: 30,
price: 129,
quantity: 1,
weight: '7 inch',
discount: 20,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 31,
price: 200,
quantity: 1,
weight: '12 inch',
discount: 25,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 32,
price: 500,
quantity: 1,
weight: '18 inch',
discount: 40,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 33,
price: 700,
quantity: 1,
weight: '20 inch',
discount: 30,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
],
},
];
let i = 0;
let j = 0;
for (i; i < data.length; i++) {
for (j; j < data[i].variant.length; j++) {
data[i].variant.forEach(e => {
e.myKey = 0;
});
}
}
console.log('data : ' + JSON.stringify(data));
const data = [
{
id: 13,
product_name: 'Onion Pizza',
image: '26238.jpg',
category: {
id: 1,
name: 'Restaurants',
image: 'restaurant.png',
created_at: '2022-02-02T07:59:05.000000Z',
updated_at: '2022-02-15T10:58:49.000000Z',
},
status: '1',
created_at: '2022-02-19T12:22:09.000000Z',
updated_at: '2022-03-02T09:43:53.000000Z',
add_in_cart: false,
quantity_in_cart: 0,
add_in_wishlist: false,
variant: [
{
id: 34,
price: 140,
quantity: 10,
weight: '7 inch',
discount: 20,
product_id: 13,
created_at: '2022-03-02T12:46:06.000000Z',
updated_at: '2022-03-02T12:46:06.000000Z',
},
{
id: 35,
price: 350,
quantity: 5,
weight: '14 inch',
discount: 20,
product_id: 13,
created_at: '2022-03-02T12:46:06.000000Z',
updated_at: '2022-03-02T12:46:06.000000Z',
},
],
},
{
id: 15,
product_name: 'Veg Fresh Pizza',
image: '816404.jpg',
category: {
id: 1,
name: 'Restaurants',
image: 'restaurant.png',
created_at: '2022-02-02T07:59:05.000000Z',
updated_at: '2022-02-15T10:58:49.000000Z',
},
status: '1',
created_at: '2022-03-01T12:40:15.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
add_in_cart: false,
quantity_in_cart: 0,
add_in_wishlist: false,
variant: [
{
id: 30,
price: 129,
quantity: 1,
weight: '7 inch',
discount: 20,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 31,
price: 200,
quantity: 1,
weight: '12 inch',
discount: 25,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 32,
price: 500,
quantity: 1,
weight: '18 inch',
discount: 40,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
{
id: 33,
price: 700,
quantity: 1,
weight: '20 inch',
discount: 30,
product_id: 15,
created_at: '2022-03-02T12:27:28.000000Z',
updated_at: '2022-03-02T12:27:28.000000Z',
},
],
},
];
let i = 0;
let j = 0;
for (i; i < data.length; i++) {
for (j; j < data[i].variant.length; j++) {
data[i].variant.forEach(e => {
e.myKey = 0;
});
}
}
console.log('data : ' + JSON.stringify(data));
You could take a Map and iterate the objects and seach for nested array.
This approach uses a short circuit if no more nodes are eligible for update.
function update(array, nodes) {
return array.some(o => {
var key = o.key.toString();
if (nodes.has(key)) {
o.edit = nodes.get(key);
nodes.delete(key);
if (!nodes.size) return true;
}
return update(Object.values(o).find(Array.isArray) || [], nodes);
});
}
var data = [{ name: 'database', checked: true, key: 1, schemas: [{ name: "schema1", checked: true, key: 2, tables: [{ name: "table1", checked: true, key: 3, columns: [{ name: "column2", checked: true, key: 5 }] }] }, { name: "schema2", checked: true, key: 6, tables: [{ name: "table2", checked: true, key: 7, columns: [{ name: "column1", checked: true, key: 8 }] }] }] }],
keyValues = { 8: 'column4', 6: 'schema4' };
update(data, new Map(Object.entries(keyValues)));
console.log(data);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Hi I have following model of a document in mongodb
Schema is
const ProductionsSchema=new Schema({
name: {type: String, required: true, unique: true},
isActive: {type: Boolean, default: true},
locations: [{
name: {type: String},
isActive : {type: Boolean, default: false}
}],
trackno: {type: String}
})
Productions:[{
_id: 125,
name: 'John Smith',
locations: [{ name: 'Boston', isActive: true}]
isActive: true,
trackno: 2123
},
{
_id: 126,
name: 'Moe Adam',
locations: [{ name: 'Chicago', isActive: true}]
isActive: true,
trackno: 5663
},
{
_id: 126,
name: 'Henry Noel',
locations: [{ name: 'Houston', isActive: false}]
isActive: true,
trackno: 4552
},
{
_id: 128,
name: 'Tim Johnson',
locations: [{ name: 'Denver', isActive: true}]
isActive: false,
trackno: 6672
}
]
I am trying to find list of with both isActive true
Productions.find({"isActive" : true , "locations.isActive": true}, (err, list)=>{
if(err){
callback(err);
}
callback(null, list)
})
I am trying to write query so both isActive are true. In above sample data only first two records should be in the answer. But I keep getting all the records even ones with 'false' I even tried $elemMatch on locations.isActive still didnt work.
Please let me know how I can fix this so that I only get result that contains only true values for both isActive.
As the original comment explained, the only query conditions you need are:
{ isActive: true, "locations.isActive": true }
This is a basic AND condition, and you don't need any special operators just to verify a condition is met on a single property anywhere in an array, which is all you are asking.
Since this works exactly as expected, I can only think to show you a full working listing to use as a basis to work out what you are doing differently thus causing you to not get the same result as what is expected.
const { Schema } = mongoose = require('mongoose');
const uri = 'mongodb://localhost:27017/productions';
const opts = { useNewUrlParser: true };
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('debug', true);
const productionSchema = new Schema({
name: String,
isActive: { type: Boolean, default: true },
locations: [{
name: String,
isActive: { type: Boolean, default: false }
}],
trackno: Number
})
const Production = mongoose.model('Production', productionSchema);
const data =
[
{
name: 'John Smith',
locations: [{ name: 'Boston', isActive: true}],
isActive: true,
trackno: 2123
},
{
name: 'Moe Adam',
locations: [{ name: 'Chicago', isActive: true}],
isActive: true,
trackno: 5663
},
{
name: 'Henry Noel',
locations: [{ name: 'Houston', isActive: false}],
isActive: true,
trackno: 4552
},
{
name: 'Tim Johnson',
locations: [{ name: 'Denver', isActive: true}],
isActive: false,
trackno: 6672
}
];
const log = data => console.log(JSON.stringify(data, undefined, 2));
(async function() {
try {
const conn = await mongoose.connect(uri, opts);
// clean data
await Promise.all(
Object.entries(conn.models).map(([k, m]) => m.deleteMany())
);
// set up
await Production.insertMany(data);
// Query
let query = { isActive: true, "locations.isActive": true };
let results = await Production.find(query);
log(results);
} catch(e) {
console.error(e)
} finally {
mongoose.disconnect()
}
})()
Which outputs the two expected documents:
Mongoose: productions.deleteMany({}, {})
Mongoose: productions.insertMany([ { isActive: true, _id: 5c7f7e9367daed19d6773e9b, name: 'John Smith', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9c, name: 'Boston' } ], trackno: 2123, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9d, name: 'Moe Adam', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773e9e, name: 'Chicago' } ], trackno: 5663, __v: 0 }, { isActive: true, _id: 5c7f7e9367daed19d6773e9f, name: 'Henry Noel', locations: [ { isActive: false, _id: 5c7f7e9367daed19d6773ea0, name: 'Houston' } ], trackno: 4552, __v: 0 }, { isActive: false, _id: 5c7f7e9367daed19d6773ea1, name: 'Tim Johnson', locations: [ { isActive: true, _id: 5c7f7e9367daed19d6773ea2, name: 'Denver' } ], trackno: 6672, __v: 0 } ], {})
Mongoose: productions.find({ isActive: true, 'locations.isActive': true }, { projection: {} })
[
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9b",
"name": "John Smith",
"locations": [
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9c",
"name": "Boston"
}
],
"trackno": 2123,
"__v": 0
},
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9d",
"name": "Moe Adam",
"locations": [
{
"isActive": true,
"_id": "5c7f7e9367daed19d6773e9e",
"name": "Chicago"
}
],
"trackno": 5663,
"__v": 0
}
]
I am doing an AJAX request to a JSON and getting following code as response:
{
total: "1",
items: [
{
id: 43,
title: "ThisIsTheTitle",
promoted: false,
sticky: false,
weight: 10,
created: {
timestamp: 1482054,
formatted: "17/01/2017"
},
url: "http://...",
airdate: {
timestamp: 1484980,
formatted: "17/01/2017"
},
video: {
id: 43,
number_of_views: 1,
duration: {
seconds: 50,
formatted: "00:00"
},
required_login: false
},
program: {
id: 25,
url: "http://...",
title: "ProgrammaTitel"
},
image: {
uri: "public://...",
full: "http://..."
},
tags: [
{
id: "4",
name: "Map"
},
{
id: "7",
name: "Aflevering2"
}
]
}
]
}
Now I push this data into my own JSArray. Note there is now only 1 response-item but more will be added.
I want to retrieve specific object-data based on the name of a tag of the object (item > tags > name = 'Aflevering2')
So I would like the data from the object where the tag name is 'Aflevering2'.
Any advice? Thanks!
You can find the items with a combination of filter() and some():
obj.items.filter(v => v.tags.some(k => k.name === 'Aflevering2'));
let obj = {
total: "1",
items: [
{
id: 43,
title: "ThisIsTheTitle",
promoted: false,
sticky: false,
weight: 10,
created: {
timestamp: 1482054,
formatted: "17/01/2017"
},
url: "http://...",
airdate: {
timestamp: 1484980,
formatted: "17/01/2017"
},
video: {
id: 43,
number_of_views: 1,
duration: {
seconds: 50,
formatted: "00:00"
},
required_login: false
},
program: {
id: 25,
url: "http://...",
title: "ProgrammaTitel"
},
image: {
uri: "public://...",
full: "http://..."
},
tags: [
{
id: "4",
name: "Map"
},
{
id: "7",
name: "Aflevering2"
}
]
}
]
}
let items = obj.items.filter(v => v.tags.some(k => k.name === 'Aflevering2'));
console.log(items);