Map Array of Array? - node.js

I have a crazy array look like this:
const data = [
[{ Name: 'Name 1', Block: [{Id: "1"}, {Id: "2"}] }],
[{ Name: 'Name 2', Block: [{Id: "3"}, {Id: "4"}] }],
]
I want to map Block to a single array to look like this:
[ { Id: '1' },
{ Id: '2' },
{ Id: '3' },
{ Id: '4' }
]
I have tried doing like this:
const data = [
[{ Name: 'Name 1', Block: [{Id: "1"}, {Id: "2"}] }],
[{ Name: 'Name 2', Block: [{Id: "3"}, {Id: "4"}] }],
]
const idList = data.map(blockData => {
return blockData[0].Block;
});
console.log(idList)
What did I do wrong?

.map will create a new item for every index of the old array. If your input array has 2 items, the output array will also only have 2 items - but you want 4 items, so .map won't work. Use flatMap instead, to flatten:
const data = [
[{ Name: 'Name 1', Block: [{Id: "1"}, {Id: "2"}] }],
[{ Name: 'Name 2', Block: [{Id: "3"}, {Id: "4"}] }],
];
const idList = data.flatMap(([{ Block }]) => Block);
console.log(idList)
flatMap is only implemented on newer implementations, though - otherwise, use a polyfill or a different method, like reduceing into an array:
const data = [
[{ Name: 'Name 1', Block: [{Id: "1"}, {Id: "2"}] }],
[{ Name: 'Name 2', Block: [{Id: "3"}, {Id: "4"}] }],
];
const idList = data.reduce((a, [{ Block }]) => a.concat(Block), []);
console.log(idList)

your data is an array inside array so you should use map twice, Buth that will give you an array with 2 elements now you need to reduce or flatten the resulting array to get the desired output.
data.map(a=>{return a[0].Block.map(b=>{ return b})}).reduce((o, m) => [...m, ...o], [])

The most succinct way to do it would be with a reduce statement:
const reducer = (a, b) => a.concat(b[0].Block);
const idList = data.reduce(reducer, []);
This way it will be much clearer what you are trying to do.

Related

How to bulk update in sequelize with experssJs

I have the follwing set of data
const data = [{
name: 'test2',
desc: test2,
id: 2,
},
{
name: 'test3',
desc: test3,
id: 3,
},
{
name: 'test4',
desc: test4,
id: 4,
},
]
I want to update using sequelize, i don't want to use any kind of loop to update. However I've tried bulkCreate with updateOnDuplicate
await models.project.bulkCreate(data, {
updateOnDuplicate: ['id'],
},
But I'm not able to update and getting sequalize error. Can anyone tell the optimized solutions for the same?

Convert DB response from object to array

I have the following schema:
const mySchema = new mongoose.Schema({
name: String,
subscribers: [ { name: String } ]
})
const myModel = mongoose.model('User', mySchema, 'users')
and I have this code in one of my controllers:
const allOfHisSubscribers = await myModel.findById(req.params.id).select('subscribers')
I want the database response of the await myModel.findByid call to be:
[
{ name: 'x' },
{ name: 'y' },
{ name: 'z' },
]
However, the code above is returning:
{
subscribers: [
{ name: 'x' },
{ name: 'y' },
{ name: 'z' },
]
}
I don't want the JavaScript way of doing it, I know you can use something like Array.prototype.map to get the result, but I am using a middleware, so I can only use the mongoose or MongoDB way of doing it (if possible).
Got it :D, if not, let me know in the comments 🌹

How i can filter and return a nested array of object?

someone can help me?
i have a data structure like as:
contracts: [
0: {closedRequest: [{id: ... , name: ... } , {id: ... , name: ... }, {id: ... , name: ... }]},
1: {closedRequest: [{id: ... , name: ... } , {id: ... , name: ... }, {id: ... , name: ... }]},
]
Now i would filter this object for delete element in closedRequest that have a determined Id.
I try to use with filter, but array not change.
How i can do it?
Example, i want exclude all element that have id (on closedRequest) = 3
so, if i have this structure:
contracts: [
0: {closedRequest: [{id: 2 , name: "a"} , {id: 3 , name: "b"}, {id: 4 , name: "c" }]},
1: {closedRequest: [{id: 2 , name: "a"} , {id: 3 , name: "b"}, {id: 4 , name: "c" }]},
]
i want have:
contracts: [
0: {closedRequest: [{id: 2 , name: "a"} {id: 4 , name: "c" }]},
1: {closedRequest: [{id: 2 , name: "a"} {id: 4 , name: "c" }]},
]
Example of my code:
client.contracts.forEach((c) =>
c.closedRequests.filter((cr) => cr.requestID != requestID)
);
i want have same object, but with filed of closedRequest edited.
Thanks
Assuming each item of contracts array consists of many fields, you can use array.map to transform the old array into a new one and array.filter in order to filter a nested array:
let contracts = [
{ closedRequest: [{id: 2 , name: "a"} , {id: 3 , name: "b"}, {id: 4 , name: "c" }] },
{ closedRequest: [{id: 2 , name: "a"} , {id: 3 , name: "b"}, {id: 4 , name: "c" }] }
];
let filteredContracts = contracts.map(contract =>
({ ...contract, closedRequest : contract.closedRequest.filter(x => x.id !== 3) }));
console.log(filteredContracts);

Using Highland.js to hydrate one stream with data from another

Say I have two Highland streams:
import hl from 'highland'
const accounts = hl([
{id: 1, name: "Bob"},
{id: 2, name: "Chris"},
]);
const accountData = hl([
{id: 1, age: 21},
{id: 2, age: 43},
]);
I'd like to map over the accounts stream and merge in the extra data from accountData so the result looks something like this:
Highland.Stream<[
{id: 1, name: "Bob", age: 21},
{id: 2, name: "Chris", age: 43},
]>
This is something that's pretty simple with normal arrays but I was wondering if it were possible when using streams.
import hl from 'highland';
const accounts = hl([
{ id: 1, name: 'Bob' },
{ id: 2, name: 'Chris' }
]);
const accountData = hl([
{ id: 1, age: 21 },
{ id: 2, age: 43 }
]);
hl([ accounts, accountData ])
.merge()
.reduce(new Map(), (accum, account) => {
const { id } = account;
const mergedAccount = Object.assign({}, accum.get(id), account);
return accum.set(id, mergedAccount);
})
.map(map => [ ...map.values() ])
.doto(console.log)
.done(() => {});
Output:
[
{ id: 1, name: 'Bob', age: 21 },
{ id: 2, name: 'Chris', age: 43 }
]

How can I select document with conditional subdocs?

I need to find documents with Mongoose that contains at least one subdocument, respecting the $elemMatch condition.
My main doc sample is like this:
{
desc: 'Sample',
user: 10,
prices: [{ code: 1, price: 10 }, { code: 2, price: 0 }]
}
I need the documents that contains at least one subdoc with price bigger than 0. If doc no have price bigger than 0, the main doc may be discarded.
With $elemMatch, I can filter the subdocs, but not the main doc:
Prod.find({ user: 10}, { prices: { $elemMatch: { price: { $gt: 0 } } } })
With this, I have the document:
[{
desc: 'Sample',
user: 10,
prices: []
}]
When should it be:
[]
How can I do this?

Resources