Need to filter data date wise - javascript

I have some query result data like..
"results": [
{
"activityId": "7",
"universityId": "23",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-10T22:25:29.798Z"
},
{
"activityId": "6",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-09T23:48:23.554Z"
},
{
"activityId": "5",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}
]
Now I need to filter the data like:
[
{
title: 2022-04-10 (here createdAt value),
value: {
"activityId": "5",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat"
}
}
]
I am using nestJS.
const allActivity = [];
Promise.all(
results.map((value) => {
if (allActivity.length <= 0) {
const obj = {
title: value.createdAt,
values: value,
};
allActivity.push(obj);
}
}),
);
I just need to filter the data with this format or just need to complete my function that I have written below.

You can simply use
select * from data where createdAt like '2022-04-10%'
The returned table with this query will be in the same format that you need.

try this map function
const results = [{
"activityId": "7",
"universityId": "23",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-10T22:25:29.798Z"
},
{
"activityId": "6",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-09T23:48:23.554Z"
},
{
"activityId": "5",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}
]
const mapped = results.map(({
createdAt,
...value
}) => {
return {
title: createdAt.split('T')[0],
value
}
})
console.log(mapped)

You can check this implementation with reduce
const results = [{
"activityId": "7",
"universityId": "23",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-10T22:25:29.798Z"
},
{
"activityId": "6",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-09T23:48:23.554Z"
},
{
"activityId": "5",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}, {
"activityId": "8",
"universityId": "17",
"studentId": "25",
"content": "New testing",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}
]
//format your date from `2022-04-08T23:48:21.841Z` to `2022-04-08`
const formatDate = (date) => date.split('T')[0]
const finalResult = results
.reduce((finalList, item) => {
const currentItemFormattedDate = formatDate(item.createdAt)
const foundItem = finalList.find(addedItem => formatDate(addedItem.title) === currentItemFormattedDate)
//if it's not in the final list, we need to create a new title
if (!foundItem) {
finalList.push({
title: currentItemFormattedDate,
value: [{
...item
}]
})
} else {
//if it's in the final list, we just need to push value
foundItem.value.push({
...item
})
}
return finalList
}, [])
console.log(finalResult)
The easier way with groupBy, but instead of title, I'm using keys for date representation
const results = [{
"activityId": "7",
"universityId": "23",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-10T22:25:29.798Z"
},
{
"activityId": "6",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-09T23:48:23.554Z"
},
{
"activityId": "5",
"universityId": "17",
"studentId": "25",
"content": "Add course in cart",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}, {
"activityId": "8",
"universityId": "17",
"studentId": "25",
"content": "New testing",
"activityType": "chat",
"createdAt": "2022-04-08T23:48:21.841Z"
}
]
const formatDate = (date) => date.split('T')[0]
//groupBy is not fully supported for all browsers, so I use vanilla Javascript for it
const groupBy = function(xs, key) {
return xs.reduce(function(rv, x) {
(rv[x[key]] = rv[x[key]] || []).push(x);
return rv;
}, {});
};
const finalResult = groupBy(results.map(item => ({...item, createdAt: formatDate(item.createdAt)})), "createdAt")
console.log(finalResult)

Assuming you want to group by createdAt by trimming time.
const results = [{activityId:"6",universityId:"17",studentId:"25",content:"Add course in cart",activityType:"chat",createdAt:"2022-04-09T23:48:23.554Z"},{activityId:"5",universityId:"17",studentId:"25",content:"Add course in cart",activityType:"chat",createdAt:"2022-04-08T23:48:21.841Z"},{activityId:"9",universityId:"11",studentId:"26",content:"Add course in cart",activityType:"chat",createdAt:"2022-04-08T23:48:21.841Z"}];
const map = new Map();
for (const ele of results) {
const date = new Intl.DateTimeFormat('en-GB', {
dateStyle: 'medium',
}).format(new Date(ele.createdAt));
if (map.has(date)) {
map.set(date, [ele, ...map.get(date)]);
continue;
}
map.set(date, [ele]);
}
const output = Object.fromEntries(map.entries());
console.log(output);

Related

How to convert flat data to hierarchical JSON?

I use a fake api with this json, I still haven't been able to with this function, I need to convert the structure to look like this and I need to convert this data and then unconvert when saving
so that I change the parameters blockId to id, blockParent to parent.
{
"blocks": [
{
"blockId": "12",
"name": "Sierra",
"abrv": "Sir",
"blockParent": "0"
},
{
"blockId": "23",
"name": "Velasco",
"abrv": "Vel",
"blockParent": "12"
},
{
"blockId": "32",
"name": "UnitOne",
"abrv": "Uni",
"blockParent": "23"
},
{
"blockId": "48",
"name": "Vani",
"abrv": "Van",
"blockParent": "12"
},
{
"blockId": "57",
"name": "UnitTwo",
"abrv": "UniTwo",
"blockParent": "48"
}
]
}
const flatToTree = (blocks: IListBlocks[]) => {
const array: IListBlocks[] = []
const children: IListBlocks[] = []
blocks.forEach((block) => {
if (block.blockParent === block.blockId) {
array.push(block)
} else {
children.push(block)
}
})
array.forEach((block) => {
block.children = children.filter(
(child) => child.blockParent === block.blockId,
)
})
return array
}
{
"id": "12",
"title": "Sierra",
"subtitle": "Sir",
"parent": "0",
"children": [
{
"id": "13",
"title": "Sierra",
"subtitle": "Sir",
"parent": "12",
}
]
}

Updating array of objects with recursive function (Mapping replies to comments dynamically)

I am receiving a list of comments from a graphql backend in the following format:
[
{
"__typename": "Comment",
"id": "1",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "test 1"
},
{
"__typename": "Comment",
"id": "2",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "this is a comment"
},
{
"__typename": "Comment",
"id": "34",
"userId": "1",
"postId": "1",
"parentCommentId": "1",
"content": "reply to test1"
},
{
"__typename": "Comment",
"id": "35",
"userId": "1",
"postId": "1",
"parentCommentId": "34",
"content": "nested reply to \"reply to test1\"\n\n"
},
{
"__typename": "Comment",
"id": "36",
"userId": "1",
"postId": "1",
"parentCommentId": "34",
"content": "test?"
}
]
The comments with parentCommentId === null are the highest level comments, while comments where parentCommentId !== null are replies to a comment where id === parentCommentId
I would like to transform this data structure to something like:
[{
"__typename": "Comment",
"id": "1",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "test1",
"replies": [{
"__typename": "Comment",
"id": "34",
"userId": "1",
"postId": "1",
"parentCommentId": "1",
"content": "reply to test1",
"replies": [{
"__typename": "Comment",
"id": "35",
"userId": "1",
"postId": "1",
"parentCommentId": "34",
"content": "reply to test1"
}]
}]
},
{
"__typename": "Comment",
"id": "2",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "this is a comment",
"replies": []
}
]
I have the following function to do the data transformation:
function formatData(comments: Array < IComment > ) {
let commentList = Array < IComment > ();
// add comments without `parentCommentId` to the list.
// these are top level comments.
for (let i = 0; i < comments.length; i++) {
if (!comments[i].parentCommentId) {
commentList.push({ ...comments[i],
replies: []
});
}
}
for (let i = 0; i < comments.length; i++) {
if (comments[i].parentCommentId) {
const reply = comments[i];
mapReplyToComment(commentList, reply);
}
}
return commentList;
function mapReplyToComment(
commentList: Array < IComment > ,
reply: IComment
): any {
return commentList.map((comment) => {
if (!comment.replies) {
comment = { ...comment,
replies: []
};
}
if (comment.id === reply.parentCommentId) {
comment.replies.push(reply);
return comment;
} else {
return mapReplyToComment(comment.replies, reply);
}
});
}
}
However this only works for one level deep into the object tree. so I am getting the replies of a main comment, but replies to replies are not added to the object.
this is what I am getting now:
[{
"__typename": "Comment",
"id": "1",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "test1",
"replies": [{
"__typename": "Comment",
"id": "34",
"userId": "1",
"postId": "1",
"parentCommentId": "1",
"content": "reply to test1"
// -- I should have here another node of "replies"
}]
},
{
"__typename": "Comment",
"id": "2",
"userId": "1",
"postId": "1",
"parentCommentId": null,
"content": "this is a comment",
"replies": []
}
]
Could you please point out what am I doing wrong and provide some explanation?
Thanks in advance
Edit:
based on #Nina Scholz's comment I came up with this solution:
function formatData(data: Array < IComment > , root: string) {
const temp: any = {};
data.forEach((comment: IComment) => {
const parentCommentId = comment.parentCommentId ? ? root;
if (temp[parentCommentId] == null) {
temp[parentCommentId] = {};
}
if (temp[parentCommentId].replies == null) {
temp[parentCommentId].replies = [];
}
if (temp[comment.id] == null) {
temp[parentCommentId].replies.push(
Object.assign((temp[comment.id] = {}), comment)
);
} else {
temp[parentCommentId].replies.push(
Object.assign(temp[comment.id], comment)
);
}
});
return temp[root].replies;
}
You could take a single iteration with the help of an object which keeps the references of parent to children and children to parent.
const
getTree = (data, root) => {
const t = {};
data.forEach(o =>
((t[o.parentCommentId] ??= {}).replies ??= []).push(
Object.assign(t[o.id] ??= {}, o)
)
);
return t[root].replies;
},
data = [{ __typename: "Comment", id: "1", userId: "1", postId: "1", parentCommentId: null, content: "test 1" }, { __typename: "Comment", id: "2", userId: "1", postId: "1", parentCommentId: null, content: "this is a comment" }, { __typename: "Comment", id: "34", userId: "1", postId: "1", parentCommentId: "1", content: "reply to test1" }, { __typename: "Comment", id: "35", userId: "1", postId: "1", parentCommentId: "34", content: "nested reply to \"reply to test1\"\n\n" }, { __typename: "Comment", id: "36", userId: "1", postId: "1", parentCommentId: "34", content: "test?" }],
tree = getTree(data, null);
console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Since the other answer was hard to understand for me, I will post mine as well which splits the steps into standalone functions:
(Note that I added the replies array in your sample data)
let data = [{ "__typename": "Comment", "id": "1", "userId": "1", "postId": "1", "parentCommentId": null, "content": "test 1", "replies": [] },
{ "__typename": "Comment", "id": "2", "userId": "1", "postId": "1", "parentCommentId": null, "content": "this is a comment", "replies": [] },
{ "__typename": "Comment", "id": "34", "userId": "1", "postId": "1", "parentCommentId": "1", "content": "reply to test1", "replies": [] },
{ "__typename": "Comment", "id": "35", "userId": "1", "postId": "1", "parentCommentId": "34", "content": "nested reply to \"reply to test1\"\n\n", "replies": [] },
{ "__typename": "Comment", "id": "36", "userId": "1", "postId": "1", "parentCommentId": "34", "content": "test?", "replies": [] }
]
function findLowestComment(dataArray) {
for (let i = 0; i < dataArray.length; i++) {
let comment = dataArray[i]
isLowest = true
if (comment.parentCommentId == null) {
continue
}
for (let j = 0; j < dataArray.length; j++) {
if (dataArray[j].id != comment.id &&
dataArray[j].parentCommentId == comment.id &&
dataArray[j].parentCommentId != null) {
isLowest = false;
break
}
}
if (isLowest) {
return i
}
}
}
function insertIntoParent(dataArray, commentIndex) {
for (let j = 0; j < dataArray.length; j++) {
if (dataArray[j].id == dataArray[commentIndex].parentCommentId) {
dataArray[j].replies.push(dataArray[commentIndex])
dataArray.splice(commentIndex, 1)
break
}
}
}
function mapComments(dataArray) {
for (let j = 0; j < dataArray.length; j++) {
let lowestIndex = findLowestComment(dataArray)
insertIntoParent(dataArray, lowestIndex)
}
}
mapComments(data)
console.log(JSON.stringify(data, undefined, 2))

Filter an array of objects by another object of filters

I have an array of objects who follow this structure below:
{
"level": 1
"objectId": "3756"
"objectIdNo": 35636
"wpId": "3635473"
}
I now want to filter an array of these objects by another object. This filterObject would have the structure below:
// filterObject
{
level: "2"
objectId: "10"
wpId: "1"
}
But this filterObject doesn't always have all the key-value pairs because they get set manually in the UI. As a result the filterObject can also look like this:
{
level: "2"
}
My goal is to return a new array of filteredObjects who match this filterObject. When only one filter exists on the filterObject I want to return all objects that match this one key-value pair. But if more filters exist on the filterObject I want to return all objects that match both key-value pairs (not only one).
Example:
This is the data I want to filter:
[
{
"level": "1"
"objectId": "11"
"objectIdNo": "320"
"wpId": "123"
},
{
"level": "2"
"objectId": "12"
"objectIdNo": "321"
"wpId": "123"
},
{
"level": "2"
"objectId": "13"
"objectIdNo": "322"
"wpId": "120"
},
]
1.
If this is my filterObject:
{
"level": "2"
}
Return:
[
{
"level": "2"
"objectId": "12"
"objectIdNo": "321"
"wpId": "123"
},
{
"level": "2"
"objectId": "13"
"objectIdNo": "322"
"wpId": "120"
},
]
2.
If this is my filterObject:
{
"level": "2",
"wpId": "123"
}
Return:
[
{
"level": "2"
"objectId": "12"
"objectIdNo": "321"
"wpId": "123"
},
]
I hope that explains the logic I want to achieve which I couldn't implement myself. I would appreciate some ideas or applicable functions.
This is what I already tried in React. The data variable holds the array of objects and the filter variable hold the filterObjects.
useEffect(() => {
if (data) {
const filtered = data.filter((task) => {
if (!filter) {
return true;
}
return (
task.level === filter.level ||
task.objectId === filter.objectId ||
task.wpId === filter.wpId
);
});
setFilteredTasks(filtered);
}
}, [filter]);
With my attempt, if I just set the one filter key-value pair I get an empty array,
You can achieve this result using filter, Object.keys, and every.
You have to use filter and pass predicate that tell whether it is included in the final result.
In predicate, loop over all properties on the filters object and match if it is present in data or not. Simple
data.filter((o) =>Object.keys(filters).every((k) => filters[k] === o[k]));
const data = [{
level: "1",
objectId: "11",
objectIdNo: "320",
wpId: "123",
},
{
level: "2",
objectId: "12",
objectIdNo: "321",
wpId: "123",
},
{
level: "2",
objectId: "13",
objectIdNo: "322",
wpId: "120",
},
];
const filters = {
level: "2",
wpId: "123",
};
const result = data.filter((o) =>
Object.keys(filters).every((k) => filters[k] === o[k])
);
console.log(result);
This should do the trick!
const exampleData = [
{
"level": "1",
"objectId": "11",
"objectIdNo": "320",
"wpId": "123",
},
{
"level": "2",
"objectId": "12",
"objectIdNo": "321",
"wpId": "123",
},
{
"level": "2",
"objectId": "13",
"objectIdNo": "322",
"wpId": "120",
},
];
const filterObject1 = {
"level": "2",
}
const filterObject2 = {
"level": "2",
"wpId": "123"
}
function filter(data, filterObject) {
const filterValues = Object.entries(filterObject)
let filteredData = data
for(const [filterKey, filterValue] of filterValues) {
filteredData = filteredData.filter(obj => obj[filterKey] === filterValue)
}
return filteredData
}
console.log(filter(exampleData, filterObject1))
console.log(filter(exampleData, filterObject2))
You can do like this:
const data = [
{
level: "1",
objectId: "11",
objectIdNo: "320",
wpId: "123",
},
{
level: "2",
objectId: "12",
objectIdNo: "321",
wpId: "123",
},
{
level: "2",
objectId: "13",
objectIdNo: "322",
wpId: "120",
},
];
const filterObject = {
level: "2",
wpId: "123",
};
const result = data.filter((item) => {
let flag = true;
Object.keys(filterObject).forEach((key) => {
if (item[key] !== filterObject[key]) {
flag = false;
return;
}
});
return flag;
});
console.log(result);
const input = [ { "level": "1", "objectId": "11", "objectIdNo": "320", "wpId": "123" }, { "level": "2", "objectId": "12", "objectIdNo": "321", "wpId": "123", }, { "level": "2", "objectId": "13", "objectIdNo": "322", "wpId": "120" }, ]
const filter = { "level": "2", "wpId": "123" };
const filteredOutput = input.filter( obj => {
return Object.keys(filter).every( filterKeys => {
return obj[filterKeys] === filter[filterKeys]
});
});
console.log(filteredOutput);

Nested JSON - Join sub-object

How can I remove sub-objects?
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}]
}]
[{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory_2kg": "5",
"current_inventory_5kg": "5",
"current_inventory_10kg": "5",
"current_inventory_20kg": "5",
}]
Use Object.keys() and a forEach loop
var x =[
{
"id": "1",
"desc": "SOME PRODUCT",
"codigo": "CODE-28",
"codigoBarras": "2000000001",
"unidade": "PCT",
"price": "24.15",
"current_inventory": [
{
"2kg": "5",
"5kg": "5",
"10kg": "5",
"20kg": "5",
"productId": "1"
}
]
}
]
x[0].current_inventory.forEach(e=>{
Object.keys(e).forEach(j=>{
x[0]['current_inventory_'+j]=e[j];
})
delete x[0].current_inventory
})
console.log(x)
Use Object.entries and reduce will simplify.
const data = [
{
id: "1",
desc: "SOME PRODUCT",
codigo: "CODE-28",
codigoBarras: "2000000001",
unidade: "PCT",
price: "24.15",
current_inventory: [
{
"2kg": 5,
"5kg": 5,
"10kg": 5,
"20kg": 5,
productId: 1
}
]
}
];
const [first] = data;
const updated = Object.entries(first).reduce((acc, [key, value]) => {
if (Array.isArray(value)) {
value.forEach(item =>
Object.entries(item).forEach(
([cKey, cValue]) => (acc[`${key}_${cKey}`] = cValue)
)
);
} else {
acc[key] = value;
}
return acc;
}, {});
console.log(updated);
THANK YOU VERY MUCH!!!
Solved using the code below:
data is de object
estoqueFracionado is the sub-object
for (let [key, value] of Object.entries(data)) {
value.estoqueFracionado.forEach (e => {
Object.keys(e).forEach(j => {
value['estoqueFracionado_' + j] = e[j]
})
delete value.estoqueFracionado
})
}

Delete duplicate value from array of array

I have an object array and I want to avoid to duplicate value with a specific key value.
This is an objectArray.
var dept =
[
{
"department": [
{ "userName": "cds",
"userId": "33",
"userFirstname": "Chef",
"userLastname": "Jone"
},
{
"userName": "asset1",
"userId": "27",
"userFirstname": "Asset",
"userLastname": "Ann "
}
],
"comment": "",
"doc": null
},
{
"department": [
{
"userName": "audit1",
"userId": "32",
"userFirstname": "Audit",
"userLastname": "Kim"
},
{ "userName": "cds",
"userId": "33",
"userFirstname": "Chef",
"userLastname": "Jone"
}
],
"comment": "",
"doc": null
}
];
I tried to return the unduplicated object by javascript.
But the result seems different.
I can return the value from one object array. However, I feel difficulties to extract the values from array of array.
How to assign a filter array of an array?
Any help would be appreciated.
Thanks in advance.
function getUnique(dept, comp) {
const unique = dept
.map(e => e[comp])
// store the keys of the unique objects
.map((e, i, final) => final.indexOf(e) === i && i)
// eliminate the dead keys & store unique objects
.filter(e => dept[e]).map(e => dept[e]);
return unique;
}
return getUnique(dept,'userName');
I would get the result
[
{
"department": [
{ "userName": "cds",
"userId": "33",
"userFirstname": "Chef",
"userLastname": "Jone"
},
{
"userName": "asset1",
"userId": "27",
"userFirstname": "Asset",
"userLastname": "Ann "
}
],
"comment": "",
"doc": null
},
{
"department": [
{
"userName": "audit1",
"userId": "32",
"userFirstname": "Audit",
"userLastname": "Kim"
}
],
"comment": "",
"doc": null
}
];
However, I got the result
[
{
"department": [
{ "userName": "cds",
"userId": "33",
"userFirstname": "Chef",
"userLastname": "Jone"
},
{
"userName": "asset1",
"userId": "27",
"userFirstname": "Asset",
"userLastname": "Ann "
}
],
"comment": "",
"doc": null
}
]
You can use a combination of map and filter
var dept =[{"department": [{ "userName": "cds","userId": "33","userFirstname": "Chef","userLastname": "Jone"},{"userName": "asset1","userId": "27","userFirstname": "Asset","userLastname": "Ann "}],"comment": "","doc": null},{ "department": [{ "userName": "audit1","userId": "32","userFirstname": "Audit","userLastname": "Kim"},{ "userName": "cds","userId": "33","userFirstname": "Chef","userLastname": "Jone"}],"comment": "","doc": null}];
let tracker = {}
let op = dept.map(val => {
let department = val.department
let filtered = department.filter(({userId}) => {
if(tracker[userId] !== undefined ){
return false
} else {
tracker[userId] = userId
return true
}
})
return {...val,department: filtered}
})
console.log(op)

Categories

Resources