Table from the mapped JSON object consisting of many arrays - javascript

I'm working on a project in React and I'm having trouble mapping the JSON object that gets from the API. I want to get a table like this:
Image
and the JSON object looks like this:
{
"userName": "user1",
"memberCommunity": [
{
"userName": "user5",
"community": [
{
"level": 1,
"members": 3
},
{
"level": 2,
"members": 3
},
{
"level": 3,
"members": 1
}
]
},
{
"userName": "user18",
"community": []
},
{
"userName": "user2",
"community": [
{
"level": 1,
"members": 3
},
{
"level": 2,
"members": 4
},
{
"level": 3,
"members": 3
},
{
"level": 4,
"members": 6
},
{
"level": 5,
"members": 2
},
{
"level": 6,
"members": 1
}
]
}
]
}
The table image was created exactly on the data that I gave. The problem here is the proper use of the Map function, thanks to which I will get records with three users and for each of them the appropriate value in the level field. I hope I won't mix it up and you know what's going on :) Please help.

You can accomplish this with 2 reduce functions to iterate over the nested arrays.
const data = {
userName: "user1",
memberCommunity: [
{
userName: "user5",
community: [
{
level: 1,
members: 3
},
{
level: 2,
members: 3
},
{
level: 3,
members: 1
}
]
},
{
userName: "user18",
community: []
},
{
userName: "user2",
community: [
{
level: 1,
members: 3
},
{
level: 2,
members: 4
},
{
level: 3,
members: 3
},
{
level: 4,
members: 6
},
{
level: 5,
members: 2
},
{
level: 6,
members: 1
}
]
}
]
};
const format = data.memberCommunity.reduce((acc, curr) => {
return {
...acc,
[curr.userName]: curr.community.reduce((acc2, curr2) => {
return {
...acc2,
[`level ${curr2.level}`]: curr2.members
}
}, {}),
};
}, {});
console.log(format);

Related

How to find particular id using iterate Object in JavaScript

i'm trying to iterate this object with the help of for each How to find particular id using iterating object and supposed we want to
if(id == 12) {
return true;
}else{
return false;
}
This is a object
const data = {
"service": [
"BUSINESS",
"LEGAL",
"FINANCE",
"ADVERTISEMENT"
],
"service1": [
{ "id": 1 },
{ "id": 2 },
{ "id": 3 },
{ "id": 4 },
],
"service2": [
{ "id": 5 },
{ "id": 6 },
{ "id": 7 },
{ "id": 8 },
],
"service3": [
{ "id": 9 },
{ "id": 10 },
{ "id": 11 },
{ "id": 12 },
],
"service4": [
{ "id": 13 },
{ "id": 14 },
{ "id": 15 },
{ "id": 16 },
],
}
First, you check iterated object structure. If it contains array of object's or array of string's. Then find an object with ID which you need.
const data = {
service: ["BUSINESS", "LEGAL", "FINANCE", "ADVERTISEMENT"],
service1: [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }],
service2: [{ id: 5 }, { id: 6 }, { id: 7 }, { id: 8 }],
service3: [{ id: 9 }, { id: 10 }, { id: 11 }, { id: 12 }],
service4: [{ id: 13 }, { id: 14 }, { id: 15 }, { id: 16 }]
};
Object.entries(data).forEach(([_, value]) => {
if (value.every((item) => typeof item === "object")) {
if (value.find((item) => item.id === 12)) {
// do your action
}
}
});

How to check if specific values of Object items in Array

My goal: I want to modify this Array (See; Current Array with Objects) to only main properties where one or more (items) is greater than 0. In this example, the current Array should be modified by removing all object named: tags and sale_status from the Array, since there are no items is higher than 0 with count. So you only keep the Object over quotation_status.
How can I handle this the right way? I've tried various ways of looping, but can't figure it out.
Current Array with Objects
[{
"id": "tags",
"label": "Tags",
"items": [{
"key": 2,
"count": 0
}, {
"key": 1,
"count": 0
}, {
"key": 3,
"count": 0
}]
}, {
"id": "sale_status",
"label": "Status",
"items": [{
"key": "completed",
"count": 0
}, {
"key": "processing",
"count": 0
}, {
"key": "on-hold",
"count": 0
}]
}, {
"id": "quotation_status",
"label": "Status",
"items": [{
"key": "concept",
"count": 1
}]
}]
Desired output:
[{
"id": "quotation_status",
"label": "Status",
"items": [{
"key": "concept",
"count": 1
}]
}]
Current Script
function activeFilters() {
let test = test1.value
let filters = store.getters[test].filters
const result = filters.filter((o) => o.items.some((obj) => obj.count));
return result;
};
You can use filter and some to get the desired result
arr.filter((o) => o.items.some((obj) => obj.count))
const arr = [
{
id: "tags",
label: "Tags",
items: [
{
key: 2,
count: 0,
},
{
key: 1,
count: 0,
},
{
key: 3,
count: 0,
},
],
},
{
id: "sale_status",
label: "Status",
items: [
{
key: "completed",
count: 0,
},
{
key: "processing",
count: 0,
},
{
key: "on-hold",
count: 0,
},
],
},
{
id: "quotation_status",
label: "Status",
items: [
{
key: "concept",
count: 1,
},
],
},
];
const result = arr.filter((o) => o.items.some((obj) => obj.count));
console.log(result);

Convert nested Json to flat Json with parentId to every node

The following Json structure is a result of Neo4J apoc query. I want to convert this nested Json to flat Json structure as shown in the second json.
[
{
"child1": [
{
"_type": "EntityChild1",
"name": "Test222",
"_id": 2
}
],
"child2": [
{
"_type": "EntityChild2",
"name": "Test333",
"_id": 3,
"child2_child1": [
{
"_type": "EntityChild2_1",
"name": "Test444",
"_id": 6,
"child2_child1_child1": [
{
"_type": "EntityChild2_1_1",
"name": "Test555",
"_id": 7
}
]
}
]
}
],
"_type": "EntityParent",
"name": "Test000",
"_id": 1,
"child3": [
{
"_type": "EntityChild3",
"name": "Test111",
"_id": 4
}
],
"child4": [
{
"_type": "EntityChild4",
"name": "Test666",
"_id": 5
}
]
}
]
This is the result i am looking for, I also want the parentId appended to every node. If no parent is there for a particular node then it should have parentid as -1.
[
{
"_type": "EntityParent",
"name": "Test000",
"_id": 1,
"parentid": -1
},
{
"_type": "EntityChild1",
"name": "Test222",
"_id": 2,
"parentid": 1
},
{
"_type": "EntityChild2",
"name": "Test333",
"_id": 3,
"parentid": 1
},
{
"_type": "EntityChild2_1",
"name": "Test444",
"_id": 6,
"parentid": 3
},
{
"_type": "EntityChild2_1_1",
"name": "Test555",
"_id": 7,
"parentid": 6
},
{
"_type": "EntityChild3",
"name": "Test111 ",
"_id": 4,
"parentid": 1
},
{
"_type": "EntityChild4",
"name": "Test666",
"_id": 5,
"parentid": 1
}
]
Let me know if any further information is required.
You could take an iterative and recursive approach by using a function which takes an array and a parent id for the actual level.
If a property starts with child, it calls the function again with the actual _id and pushes all items to the result set.
function getFlat(array, parentid) {
return array.reduce((r, o) => {
var temp = {};
r.push(temp);
Object.entries(o).forEach(([k, v]) => {
if (k.startsWith('child')) {
r.push(...getFlat(v, o._id));
} else {
temp[k] = v;
}
});
temp.parentid = parentid;
return r;
}, []);
}
var data = [{ child1: [{ _type: "EntityChild1", name: "Test222", _id: 2 }], child2: [{ _type: "EntityChild2", name: "Test333", _id: 3, child2_child1: [{ _type: "EntityChild2_1", name: "Test444", _id: 6, child2_child1_child1: [{ _type: "EntityChild2_1_1", name: "Test555", _id: 7 }] }] }], _type: "EntityParent", name: "Test000", _id: 1, child3: [{ _type: "EntityChild3", name: "Test111", _id: 4 }], child4: [{ _type: "EntityChild4", name: "Test666", _id: 5 }] }],
flat = getFlat(data, -1);
console.log(flat);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Filtering an array based on multiple arrays inputs

I have three arrays.
1. Existing viewers array - existingViewers
New viewers array - newViewers
Permitted Viewers array - permittedViewers
permittedViewers is used for rendering the drop-down. And I wish to filter the newViewers and existingViewers entries from the permittedViewers.
I am doing this as three steps. And I am afraid this is not the optimized way. Can someone suggest the ideal way of doing this?
The expected result is
[
{
"id": 4,
"name": "name4"
},
{
"id": 5,
"name": "name5"
},
{
"id": 6,
"name": "name6"
}
]
let existingViewers = [{
"viewerId": 1,
"name": "name1"
},
{
"viewerId": 2,
"name": "name2"
}
],
newViewers = [
{
"viewerId": 3,
"name": "name3"
}
],
permittedViewers = [{
"id": 1,
"name": "name1"
},
{
"id": 2,
"name": "name2"
},
{
"id": 3,
"name": "name3"
},
{
"id": 4,
"name": "name4"
},
{
"id": 5,
"name": "name5"
},
{
"id": 6,
"name": "name6"
}
]
let grouped = [...existingViewers, ...newViewers]
let viewerFilter = grouped.map(viewer => { return viewer.viewerId; });
let filteredPermittedViewers = permittedViewers.filter(viewer => !viewerFilter.includes(viewer.id));
console.log(filteredPermittedViewers)
I'd make a Set of the ids of the first two arrays, and then filter the third by whether the set includes the id. (Sets have O(1) lookup time)
let existingViewers=[{"viewerId":1,"name":"name1"},{"viewerId":2,"name":"name2"}],newViewers=[{"viewerId":3,"name":"name3"}],permittedViewers=[{"id":1,"name":"name1"},{"id":2,"name":"name2"},{"id":3,"name":"name3"},{"id":4,"name":"name4"},{"id":5,"name":"name5"},{"id":6,"name":"name6"}];
const ids = new Set([...existingViewers, ...newViewers].map(({ viewerId }) => viewerId));
const output = permittedViewers.filter(({ id }) => !ids.has(id));
console.log(output);
You can compress all three statements into a single statement -- just replace the variable name with the statement that creates it:
let existingViewers = [{
"viewerId": 1,
"name": "name1"
},
{
"viewerId": 2,
"name": "name2"
}
],
newViewers = [
{
"viewerId": 3,
"name": "name3"
}
],
permittedViewers = [{
"id": 1,
"name": "name1"
},
{
"id": 2,
"name": "name2"
},
{
"id": 3,
"name": "name3"
},
{
"id": 4,
"name": "name4"
},
{
"id": 5,
"name": "name5"
},
{
"id": 6,
"name": "name6"
}
]
let filteredPermittedViewers = permittedViewers.filter(viewer => ! [...existingViewers, ...newViewers].map(viewer => viewer.viewerId).includes(viewer.id));
console.log(filteredPermittedViewers)

lodash merge and combine objects

I have an array of objects as below that I read from my database using sequelize ORM:
I want to have all my videos from a section, but the better I can return using sequelize is :
[{
"id": 2,
"name": "Ru",
"subsection": 1,
"Video": {
"id": 11,
"source": "sourrrccrsss22222",
"videoSubSection": 2
}
},
{
"id": 2,
"name": "Ru",
"subsection": 1,
"Video": {
"id": 12,
"source": "sourrrccrsss111",
"videoSubSection": 2
}
},
{
"id": 1,
"name": "Oc",
"subsection": 1,
"Video": {
"id": 13,
"source": "sourrrcc",
"videoSubSection": 1
}
},
{
"id": 1,
"name": "Oc",
"subsection": 1,
"Video": {
"id": 14,
"source": "sourrrcc",
"videoSubSection": 1
}
}]
Is there a way to merge and combine the objects in my array to obtain something like this :
[{
"id": 2,
"name": "Ru",
"subsection": 1,
"Video": [{
"id": 11,
"source": "sourrrccrsss22222",
"videoSubSection": 2
},{
"id": 12,
"source": "sourrrccrsss111",
"videoSubSection": 2
}]
},
{
"id": 1,
"name": "Oc",
"subsection": 1,
"Video": [{
"id": 13,
"source": "sourrrcc",
"videoSubSection": 1
},{
"id": 14,
"source": "sourrrcc",
"videoSubSection": 1
}]
}
The function that approach the most is _.mergeWith(object, sources, customizer) but the main problem I have is that I have on object and need to merge this object.
In plain Javascript, you can use Array#forEach() with a temporary object for the arrays.
var data = [{ id: 2, name: "Ru", subsection: 1, Video: { id: 11, source: "sourrrccrsss22222", VideoSubSection: 2 } }, { id: 2, name: "Ru", subsection: 1, Video: { id: 12, source: "sourrrccrsss111", VideoSubSection: 2 } }, { id: 1, name: "Oc", subsection: 1, Video: { id: 13, source: "sourrrcc", VideoSubSection: 1 } }, { id: 1, name: "Oc", subsection: 1, Video: { id: 14, source: "sourrrcc", VideoSubSection: 1 } }],
merged = function (data) {
var r = [], o = {};
data.forEach(function (a) {
if (!(a.id in o)) {
o[a.id] = [];
r.push({ id: a.id, name: a.name, subsection: a.subsection, Video: o[a.id] });
}
o[a.id].push(a.Video);
});
return r;
}(data);
document.write('<pre>' + JSON.stringify(merged, 0, 4) + '</pre>');
Maybe try transform():
_.transform(data, (result, item) => {
let found;
if ((found = _.find(result, { id: item.id }))) {
found.Video.push(item.Video);
} else {
result.push(_.defaults({ Video: [ item.Video ] }, item));
}
}, []);
Using reduce() would work here as well, but transform() is less verbose.
You can do it this way (test is your db output here)
var result = [];
var map = [];
_.forEach(test, (o) => {
var temp = _.clone(o);
delete o.Video;
if (!_.some(map, o)) {
result.push(_.extend(o, {Video: [temp.Video]}));
map.push(o);
} else {
var index = _.findIndex(map, o);
result[index].Video.push(temp.Video);
}
});
console.log(result); // outputs what you want.

Categories

Resources