Pair items in two separate arrays based on the date value - javascript

I currenty have an array of dates that looks like the following:
[
"2021-05-01",
"2021-05-02",
"2021-05-03",
]
In a separate entry array, I have entries that contain the dates that pertain to a specific date:
[
{
id: 5e24d1fa-aa66-4122-b1eb-97792f0893b0,
name: "Rodriquez Family",
selectedDates: ["2021-05-01"],
status: "submitted"
},
{
id: 269a0381-63c7-4ab6-92d8-7f7b836aee6f,
name: "Test Family",
selectedDates: ["2021-05-03"],
status: "submitted"
}
]
I am attempting to pair the two arrays for a result that would look something like the following:
[
{
date: "2021-05-01",
event: {
id: 5e24d1fa-aa66-4122-b1eb-97792f0893b0,
name: "Rodriquez Family",
selectedDates: ["2021-05-01"],
status: "submitted"
}
},
{
date: "2021-05-02",
event: null
},
{
date: "2021-05-03",
event: {
id: 269a0381-63c7-4ab6-92d8-7f7b836aee6f,
name: "Test Family",
selectedDates: ["2021-05-03"],
status: "submitted"
}
]
The issue I am running into is that as I loop through the events array and check if an event has a selected date that belongs to to a date in the dates array. It duplicates the dates for however many events there are. My function looks like the following:
const getDates = async () => {
const addEvents = dateArr.map((date) => {
return events.map((event) => {
if (event.selectedDates.includes(date)) {
return { date, event };
}
return { date, event: null, checked: false };
});
});
console.log(addEvents.flat());
};
I have included a condesandbox using react for debugging!! https://codesandbox.io/s/dawn-snow-03r59?file=/src/App.js The code sandbox will show how the dates are being duplicated.

For each dateArr element, you're iterating over events and returning a list of objects with the two specified options. Instead, you can use Array#find to check if it exists or not:
const
dateArr = ["2021-05-01", "2021-05-02", "2021-05-03"],
events = [
{ id: "5e24d1fa-aa66-4122-b1eb-97792f0893b0", name: "Rodriquez Family", selectedDates: ["2021-05-01"], status: "submitted" },
{ id: "269a0381-63c7-4ab6-92d8-7f7b836aee6f", name: "Test Family", selectedDates: ["2021-05-03"], status: "submitted" }
];
const list = dateArr.map(date => {
const event = events.find(({ selectedDates = [] }) => selectedDates.includes(date));
return event ? { date, event } : { date, event: null, checked: false };
});
console.log(list);

Related

Node Js how to fetch data from database in an hierarchical way

I'm writing a back code using NodeJs to fetch some data from backend, I want dataBase data to be like this
like this:
data = [{
name: "Admin",
id: '1',
children: [
{ name: "Admin", id: "1" },
{ name: "groupe1", id: "2" },
{
name: "groupe2", id: "1455", children: [
{ name: "groupe2", id: "1455" },
{ name: "gro", id: "5444" },
{ name: "hhrr", id: "45" }
]
}
]
}]
the idea is simple we have a list of group each group has a parent I want to display all the groups list in an hierarchical way the top one of the tree is done
Some groups are parents and groups in the same time and some others are only groups if the group is not parent we add an object with its name and ID in the array of children of his parent
if this groups is a parent that's mean it has children we add an object with its ID and name in the array of children of his parents, and we add property children for the object which is array named children with for the first time an object with the name and the id of the group etc...
i tryed to do this but it did not work
const getParentsByType = async ({ name, _id }) => {
let parentResult = [
{
id: _id,
name: name,
children: [
{
id: _id,
name: name,
},
],
},
];
parentResult= await findParent(_id, parentResult[0].children, 0);
return parentResult;
};
const findParent = async (parentId, parentResult, itemPos) => {
let children = await Models.GroupModel.find({ parent: parentId, status: true }).select('name _id');
for (let i = 0; i < children.length; i++) {
let childrenList = await Models.GroupModel.find({ parent: children[i]._id, status: true }).select('name _id');
if (childrenList.length != 0) {
parentResult.push(buildParentWithChild(children[i]._id, children[i].name));
findParent(children[i]._id,parentResult.children[i],itemPos++)
} else {
parentResult.push(buildParent(children[i]._id, children[i].name));
}
}
return parentResult
};
and this the model of the data base
const Group = mongoose.Schema({
name: {
type: String,
required: true,
},
status: {
type: Boolean,
required: true,
},
parent: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Group',
},
});
i had two days trying to resolve tis but with no result
i need some helps and Thank you
Try parsing your returned data. It validates your data as objects i dont see any problem with your function regardless i still have no idea what format your a trying to build.
let children = JSON.parse(JSON.stringify(await Models.GroupModel.find({ parent: parentId, status: true }).select('name _id')));
let childrenList = JSON.parse(JSON.stringify(await Models.GroupModel.find({ parent: children[i]._id, status: true }).select('name _id')));
If I understand you right, you want to convert the array returned by Models.GroupModel.find, and which looks like
var dbresult = [
{_id: "1", parent: null, name: "one"},
{_id: "2", parent: "1", name: "two"}
];
into a hierarchical structure. This can be done with a function that adds all children of a given parent p, including, recursively, their children. Like the following:
function children(p) {
var result = [];
for (r of dbresult) if (r.parent === p) {
var row = {_id: r._id, name: r.name};
var chld = children(r._id);
if (chld.length > 0) row.children = chld;
result.push(row);
}
return result;
}
console.log(JSON.stringify(children(null)));
Note that this approach requires only one database access (to fill the dbresult) and is therefore probably faster than your findParent function.

Javascript grouping by data from data and returning array of objects

I have 100 objects of data within an array that looks like this:
{
id: "1",
date: "2022/01/01",
name: "John",
},
{
id: "2",
date: "2022/01/02",
name: "Chris",
},
I am trying to return an array of objects by date that also returns the names.
For example:
[
{
date: "2022/01/01",
names: ["John", "Steve"...]
},
{
date: "2022/01/02",
names: ["Chris", "Rob"...]
},
]
I have tried using the reduce method:
const groupedByDate = () =>
data.reduce((itemsIterated, { date, name }) => {
if (!itemsIterated[date]) {
itemsIterated[date] = {
date,
names: [],
};
}
itemsIterated[date].names.push(name);
return itemsIterated;
}, []);
The issue is this gives me array with a key of the date and then the object with date/names but I don't know how to return just the array of objects by date.
The function groupedByDate would return an object like this -
const result = {
'2022/01/01': {
date: "2022/01/01",
names: ["John", "Steve"...]
},
'2022/01/02': {
date: "2022/01/02",
names: ["Chris", "Rob"...]
},
}
However, to retrieve it in the format you need, you would need to make use of Object.values().
Object.values(result);
/*
[
{
date: "2022/01/01",
names: ["John", "Steve"...]
},
{
date: "2022/01/02",
names: ["Chris", "Rob"...]
},
]
*/
NOTE
To learn more about Object.values() - MDN
reduce's second parameter is the initial value of the accumulator. Here, we would need to use {} instead of [] in the groupedByDate function.

Filter out array of object from array of object

I have the following data
const[myData,setMyData]=React.useState([])
React.useEffect(()=>{
let initialData=[{ email: 'user1#mail.com', date: '22-03-2020' },
{ email: 'user2#mail.com', date: '22-03-2021' },
{ email: 'user3#mail.com', date: '22-03-2021' }]
setMyData(initialData)
},[])
this data are displayed in a table with a checkbox and I have this function called everytime I push a button (after having the rows selected)
function add(datatoRemove ){
alert("datatoRemove "+JSON.stringify(datatoRemove ) )
let myArrayFiltered = myData.filter((el) => {
return datatoRemove .some((f) => {
return f.email!== el.email
});
});
alert("filtered"+JSON.stringify(myArrayFiltered ) )
setMyData( [...myArrayFiltered ])
}
The issue is that with one selection the "myArrayFiltered " returns the other 2 rows and the state is updated correctly but if I select two or all the row nothing changed and the myArrayFiltered have all 3 elements.
What am I missing here?
the final goal is:
possible scenario 1:
if
datatoRemove = [{ email: 'user1#mail.com', date: '22-03-2020' },
{ email: 'user2#mail.com', date: '22-03-2021' },
{ email: 'user3#mail.com', date: '22-03-2021' }]
then
myArrayFiltered=[] and also the myData= []
possible scenario 2:
if datatoRemove = [ { email: 'user2#mail.com', date: '22-03-2021' },{
email: 'user3#mail.com', date: '22-03-2021' }]
then
myArrayFiltered= [{ email: 'user1#mail.com', date: '22-03-2020' }]
and also myData.
You need to use this instead
let myArrayFiltered = initialData.filter((el) => {
return datatoRemove.every((f) => {
return f.email!= el.email
});
});

Javascript - Update object in array by id and move it to the first index

I have this array:
const chats = [
{ id: "chat-1", msg: { text: "World", date: (a date) } },
{ id: "chat-2", msg: { text: "Hello", date: (a date) } },
];
After receiving updates from my database, I receive this object:
// The second chat with update data
{ id: "chat-2", msg: { text: "Bye", date: (a date) } },
How can I (using ES6) replace the chat object from the original chats array and move it to the first index?
For now, I am doing this, but I am looking for a fastest way (smaller O)
// Get the modified chat
const modifiedChat = response.data;
// Search the modified chat in the chats array by id
const chatIndex = chats.findIndex(
(chat) => chat.id === modifiedChat.id
);
// Finally, using spread syntax, add the updated chat to the head of our current chats array
chats = [
modifiedChat,
...chats.slice(0, chatIndex),
...chats.slice(chatIndex + 1),
];
You can do the following,
const chats = [
{ id: "chat-1", msg: { text: "World", date: '' } },
{ id: "chat-2", msg: { text: "Hello", date: '' } },
];
const modifiedChat = { id: "chat-2", msg: { text: "Bye", date: '' } };
const newChats = [modifiedChat, ...chats.filter(item => item.id !== modifiedChat.id)];
console.log(newChats);
You can do something similar to how LRU cache works. You can now access every chat in O(1)

how to loop through multiple arrays inside an array and filter a value from it-Javascript

I'm using EXTJS framework for my code.
below is my array structure:
data = [{
id: 22,
rows: [{
id: "673627",
name: "ABS",
address: "536street"
}, {
id: "333",
name: "TEST$$",
address: "536street"
}, {
id: "999",
name: "TEST$$",
address: "536street"
}]
}, {
id: 33,
rows: [{
id: "899",
name: "TES",
address: "536street"
}, {
id: "333",
name: "TEST$$",
address: "536street"
}, {
id: "999",
name: "TES673",
address: "536street"
}]
}]
Now I want to filter the name from this array, whose value I'm comparing with say "TEST$$".
I'm doing this;
Ext.each(data, function(item) {
filter = item.rows.filter(function(name) {
return name.name === "TEST$$";
}, this);
}, this);
console.log(filter);
In this case, it returns only 1 match, where as I have 3 matches for this particular value. It returns the match from the last item in the data array and hence I dont get all the matching values, any idea how this can be looped to get all values matching?
thx!
You're reassigning the filter variable on every iteration over the data array:
filter = item.rows.filter(function(name) {
return name.name === "TEST$$";
}, this);
On the last iteration, there is only one match, the one with id of 333, so that's the only one that you see after running the Ext.each. Try pushing to an external array that doesn't get overwritten instead:
const testItems = [];
Ext.each(data, function(item) {
const filtered = item.rows.filter(row => row.name === "TEST$$")
testItems.push(...filtered);
});
console.log(testItems);
Note that there's no need to pass along the this context.
Another option is to flatMap to extract all rows to a single array first:
const output = data
.flatMap(({ rows }) => rows)
.filter(({ name }) => name === 'TEST$$');

Categories

Resources