Related
I have an array called data. How do i extract sub_data? Just need the sub_data part for each object.
const data = [
{
id: 1,
title: 'Logo'
sub_data: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands'
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
Example output will get two outputs because there is 2 objects:
const subData = [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
const subData = [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
Not very sure how to use the map function just to get sub_data in the correct structure
You can use flatMap to get sub_data in one array
const data = [
{
id: 1,
title: 'Logo',
sub_data: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands',
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
const result = data.flatMap(item => item.sub_data)
console.log(result)
If you want an array with the sub_data objects you can just map the original array:
const data = [
{
id: 1,
title: 'Logo',
'sub_data'
: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands',
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
const mappedData = data.flatMap(obj => obj.sub_data)
console.log(mappedData)
Another solution would be to use the .forEach function of javascript.
const subData = [];
data.forEach(item => subData.push(...item.sub_data))
I have an array of objects that is multi-leveled with different names that I need to populate a TreeView component :
export const application_group_one = [
{
id: uniqueId(),
name: "Application 1",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
],
},
],
},
{
id: uniqueId(),
name: "Application 2",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [],
},
],
},
];
export const application_group_two = [
{
id: uniqueId(),
name: "Application 3",
organizations: [
{
id: uniqueId(),
name: "Organization 1",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 2",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 3",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifacy 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
{
id: uniqueId(),
name: "Organization 4",
artifacts: [
{
id: uniqueId(),
name: "Artifact 1",
},
{
id: uniqueId(),
name: "Artifact 2",
},
{
id: uniqueId(),
name: "Artifact 3",
},
],
},
],
},
];
I'm able to output the Organizations but not the artifacts. Having varying names for each children object is giving me a hard time. I would like a TreeView that can expand as many levels as I want with differing names for the nest objects. :
const getTreeItemsFromData = (treeItems) => {
return treeItems.map((treeItemData) => {
let organizations = undefined;
if (treeItemData.organizations && treeItemData.organizations.length > 0) {
organizations = getTreeItemsFromData(treeItemData.organizations);
}
return <TreeItem key={treeItemData.id} nodeId={treeItemData.id} label={treeItemData.name} children={organizations} />;
});
};
const DataTreeView = ({ treeItems }) => {
return (
<TreeView defaultCollapseIcon={<ExpandMoreIcon />} defaultExpandIcon={<ChevronRightIcon />}>
{getTreeItemsFromData(treeItems)}
</TreeView>
);
};
export const Tree = () => {
return (
<div className="App">
<DataTreeView treeItems={application_group_one} />
<br />
<DataTreeView treeItems={application_group_two} />
</div>
);
};
I have JSON data that looks like this:
[
{
"id": 1,
"tags": [
"Test 1",
"Test 2",
"Test 3"
]
},
{
"id": 2,
"tags": [
"Test 2",
"Test 3",
"Test 4"
]
},
{
"id": 3,
"tags": [
"Test 3",
"Test 4"
]
}
]
I would like to transform this into data that looks like this:
[
{
"name": "Test 1",
"count": 1
},
{
"name": "Test 2",
"count": 2
},
{
"name": "Test 3",
"count": 3
},
{
"name": "Test 4",
"count": 1
}
]
I can think of some brute ways to do this, but I'm hoping there is something more performant and a little sexier? Possibly using .groupBy() or .reduce()?
Thanks for taking the time to check out my question.
I would:
parse the json
gather all tags in an array
count occurences using one of the approaches in Counting the occurrences / frequency of array elements
interface Item {
id: number,
tags: string[]
}
function countOccurences(a: string[]) {
return a.reduce(function (acc: {[key: string]: number}, curr: string) {
acc[curr] ??= 0;
acc[curr]++;
return acc;
}, {});
}
const data: Item[] = JSON.parse(json);
const tagOccurences = countOccurences(data.flatMap(o => o.tags))
Playground link
You can use reduce inside reduce to group the tags.
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {}
));
console.log(frequencies);
In TypeScript:
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
type Frequency = {
name: string,
count: number
}
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {} as Record<string, Frequency>
));
console.log(frequencies);
Playground
Using for...of iteration and a Map as a cache is a very straightforward approach... and sexy.
TS Playground
type TagsWithId = {
id: number;
tags: string[];
};
type TagCount = {
count: number;
name: string;
};
function verySexyTagCounter (input: TagsWithId[]): TagCount[] {
const map = new Map<string, number>();
for (const {tags} of input) {
for (const name of tags) {
map.set(name, (map.get(name) ?? 0) + 1);
}
}
return [...map.entries()].map(([name, count]) => ({name, count}));
}
const json = `[{"id":1,"tags":["Test 1","Test 2","Test 3"]},{"id":2,"tags":["Test 2","Test 3","Test 4"]},{"id":3,"tags":["Test 3","Test 4"]}]`;
const input: TagsWithId[] = JSON.parse(json);
const result = verySexyTagCounter(input);
console.log(result);
I'm using fullcalendar in react and all works fine until I start using the resourceRender prop and the child resources are displaying not as a part of the resource parent expansion anymore.
How show the child of a resource as to how the default designs?
This is how my resources looks like
export const resources = [
{
id: 1,
title: "Conversación estaciones",
},
{
id: 2,
title: "Renovaciones Las Americas",
},
{
id: 3,
title: "Remuneración II",
children: [
{ id: "d1", show: true, title: "Room D1" },
{ id: "d2", show: false, title: "Room D2" }
],
},
{
id: 4,
title: "Actividades cotidianas",
},
{
id: 5,
title: "Actividades rudimentarias ",
}
];
And this is how the children resources render in the calendar
this is how the children resources render in the calendar
The arrays I have
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
I would like to find the online and offline ones by comparing the two series
I want to do:
const userLists = [
{ id: 1, name: "field 1", online: true },
{ id: 2, name: "field 2", online: false },
{ id: 3, name: "field 3", online: true },
{ id: 4, name: "field 4", online: false },
];
Using Array.map and Array.some
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
var retVal=users.map(u=>{
var isOnline=onlineUsers.some(ou=> ou.id==u.id);//this will check if onlineUsers have some record with given userid
return {...u,online:isOnline}
})
console.log(retVal)
You can just traverse through the user list and you can find out the onlineuser using find and just push it in the onlineuserList.
const users = [
{ id: 1, name: "field 1" },
{ id: 2, name: "field 2" },
{ id: 3, name: "field 3" },
{ id: 4, name: "field 4" },
];
const onlineUsers = [
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
];
const userLists = [];
users.forEach(user => {
if(onlineUsers.find(q => q.id == user.id)){
userLists.push({
id: user.id,
name: user.name,
online: "true"
})
}
else{
userLists.push({
id: user.id,
name: user.name,
online: "false"
})
}
})
console.log(userLists);
a bit faster approach using Array.indexOf() and JSON.strigify()
const onlineUsers = JSON.stringify([
{ id: 1, name: "field 1" },
{ id: 3, name: "field 3" }
]);
const userList = users.map(user =>
({
...user,
online: onlineUsers.indexOf(JSON.stringify(user)) > -1
})
);
OR if you neither want to change original onlineUsers array nor declare another variable:
const userList = users.map(user =>
({ ...user, online: JSON.stringify(onlineUsers).indexOf(JSON.stringify(user)) > -1 })
);