How to get data from nested arrays in array object - javascript

I have an object array like this
array = {
"microservices": [
{
"id": 1,
"permissions": [
{
"id": 65,
"name": "Default permission"
},
{
"id": 64,
"name": "Super user Access"
}
]
},
{
"id": 2,
"permissions": []
},
{
"id": 3,
"permissions": [
{
"id": 18,
"name": "Script: Update"
},
{
"id": 15,
"name": "Application: Delete"
},
{
"id": 9,
"name": "Workspace: Create"
}
]
}
]
}
from microservices array I only want to get "permissions" arrays and stores to a new variable, I searched for it but not get any relevant solution, thanks in advance

You could use the map operator and fetch that specific property alone. Please check the below JS example.
const array = {
"microservices": [{
"id": 1,
"permissions": [{
"id": 65,
"name": "Default permission"
},
{
"id": 64,
"name": "Super user Access"
}
]
},
{
"id": 2,
"permissions": []
},
{
"id": 3,
"permissions": [{
"id": 18,
"name": "Script: Update"
},
{
"id": 15,
"name": "Application: Delete"
},
{
"id": 9,
"name": "Workspace: Create"
}
]
}
]
}
const output = []
array.microservices.map(function(x) {
output.push(...x.permissions);
})
console.log(output);

Simply you have to iterate the json object as follows. New array "Permissions" will return your data.
getPermissions(){
this.array.microservices.forEach(element => {
element.permissions.forEach(ele => {
this.permissions.push(ele);
});
});
console.log(this.permissions);
}
In advance You can use .map operator also..

This is not a specific Angular or Typescript question, but you can do it like this
const whatYouNeed = array.microservices.reduce((sum, item) => {
sum.push(item.permissions);
return sum;
}, []);
or if you want it to be a single level:
const whatYouNeed = array.microservices.reduce((sum, item) => {
sum = sum.concat(item.permissions);
return sum;
}, []);

Since you want a single array of all permissions, this would be the cleanest approach. Read about flatMap here
const permissions = array.microservices.flatMap(i => i.permissions)
console.log(permissions);
Use a polyfill for browser support. Available in the above link.

You can use ES6 map.
const permissionsArrays = array.microservices.map(microservice => microservice.permissions)

First you have an object which contains an array not an actual array. But let's ignore that for now.
array = {
"microservices": [
{
"id": 1,
"permissions": [
{
"id": 65,
"name": "Default permission"
},
{
"id": 64,
"name": "Super user Access"
}
]
},
{
"id": 2,
"permissions": []
},
{
"id": 3,
"permissions": [
{
"id": 18,
"name": "Script: Update"
},
{
"id": 15,
"name": "Application: Delete"
},
{
"id": 9,
"name": "Workspace: Create"
}
]
}
]
}
const permissions = array.microservices.map(item => {
return item.permissions;
});

So assuming that, this is the json data that your recevice:
{
"microservices": [
{
"id": 1,
"permissions": [
{
"id": 65,
"name": "Default permission"
},
{
"id": 64,
"name": "Super user Access"
}
]
},
{
"id": 2,
"permissions": []
},
{
"id": 3,
"permissions": [
{
"id": 18,
"name": "Script: Update"
},
{
"id": 15,
"name": "Application: Delete"
},
{
"id": 9,
"name": "Workspace: Create"
}
]
}
]
}
Just create an interface, to use intellisense:
export interface Microservice {
microservices?: (MicroservicesEntity)[] | null;
}
export interface MicroservicesEntity {
id: number;
permissions?: (PermissionsEntity | null)[] | null;
}
export interface PermissionsEntity {
id: number;
name: string;
}
In that way you can gain the help of intellisense, so access the data by reference the interface to the json data:
data: Microservice;
After that use map to gain the array of permission

Related

rename all key's objects JS

I want to rename some of my key's object but with a map it sounds quite difficult (I'm a newbie) here is my array :
"platforms": [
{
"id": 6,
"name": "PC (Microsoft Windows)"
},
{
"id": 11,
"name": "Xbox"
},
{
"id": 14,
"name": "Mac"
},
{
"id": 48,
"name": "PlayStation 4"
},
{
"id": 130,
"name": "Nintendo Switch"
}
],
And this is what i want it to be :
"platforms": [
{
"id": 6,
"name": "PC"
},
{
"id": 11,
"name": "Xbox"
},
{
"id": 14,
"name": "Mac"
},
{
"id": 48,
"name": "PS4"
},
{
"id": 130,
"name": "Switch"
}
],
And here is my code :
const renderedResults = results.map((result, index) => {
const platformSliced = result.platforms.slice(0,3);
return (
{platformSliced.map((platform) =>
<span className="main-game-card-platform">
{platform.name}.replace('PC (Windows Microsoft)', 'PC')
</span>
)}
);
});
It doesn't work maybe I should do a condition, but how can I write it ? Thank you
Create an object where the keys are the strings you want changed, and the values the strings that should replace the old string.
With .map() method, return a new object for each item, where the id is unchanged. The name property should look first in the new "rewrites" object if the value of name exists as a key in the object. If it does, then the value should be used, otherwise there is no rewrite and the old name should be used.
const rewrites = {
"PC (Microsoft Windows)": 'PC',
"PlayStation 4": 'PS4',
"Nintendo Switch": 'Switch'
};
const platforms = [
{
"id": 6,
"name": "PC (Microsoft Windows)"
},
{
"id": 11,
"name": "Xbox"
},
{
"id": 14,
"name": "Mac"
},
{
"id": 48,
"name": "PlayStation 4"
},
{
"id": 130,
"name": "Nintendo Switch"
}
];
const rewrittenPlatforms = platforms.map(({ id, name }) => ({
id,
name: rewrites[name] ?? name // Use rewritten name, if present, otherwise use old name.
}));
console.log(rewrittenPlatforms);

JavaScript: get all possible values of a field in a two-dimensional array

From API I get such a json:
{
"purposes": [
{
"id": 1,
"code": "for-calls"
},
{
"id": 2,
"code": "task-management"
},
{
"id": 3,
"code": "messenger"
}
],
"availabilities": [
{
"id": 1,
"code": "free"
},
{
"id": 2,
"code": "free-basic-plan"
},
{
"id": 3,
"code": "trial-version"
}
],
"ecosystems": [
{
"id": 1,
"code": "browse-widget"
},
{
"id": 2,
"code": "web-app"
},
{
"id": 3,
"code": "installation-on-your-server"
}
]
}
How do I iterate over this json to get a new array containing the field values 'code' from each element. As a result, there should be /catalog/filter/value_of_code in each element of the array.
const obj = {
"purposes": [
{
"id": 1,
"code": "for-calls"
},
{
"id": 2,
"code": "task-management"
},
{
"id": 3,
"code": "messenger"
}
],
"availabilities": [
{
"id": 1,
"code": "free"
},
{
"id": 2,
"code": "free-basic-plan"
},
{
"id": 3,
"code": "trial-version"
}
],
"ecosystems": [
{
"id": 1,
"code": "browse-widget"
},
{
"id": 2,
"code": "web-app"
},
{
"id": 3,
"code": "installation-on-your-server"
}
]
}
const arr = Object.values(obj).reduce((acc, e) => [...acc, ...e.map(o => `/catalog/filter/${o.code}`)] ,[]);
console.log( arr );
Lets say you are receiving this JSON object in serverResp object.
Now lets check if any catalogs are present in the object.
if(Object.keys(serverResp).length)
Next we shall iterate over the catalogs
Object.keys(serverResp).forEach((cat) => )
Each cat represents a catalog. Next we shall fetch array against each key inside our forloop
const catItems = serverResp[cat];
catItems will contain all the items of a particular catalog. Now lets iterate over each catItems to get the "code" value
catItems.forEach(item => console.log(item.code));
Final piece of code will look like below-
const outputArray = [];
if(Object.keys(serverResp).length) {
Object.keys(serverResp).forEach((cat)=> {
const catItems = serverResp[cat];
catItems.forEach(item =>
outputArray.push(`/catalog/filter${item.code}`));
});
}
console.log(outputArray);

How to replace an array of objects with an array including newer objects in TypeScript?

For example: I have an array of objects like this:
let arrayOfObjects: [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];
Now I want to replace or overwrite the array above with the same array, but including different values (same keys, different values):
let arrayOfObjects: [
{ "id": 0, "name": "Not Available" },
{ "id": 1, "name": "Not Ready" },
{ "id": 2, "name": "Not Started" }
];
How can this be done in TypeScript?
Try this JS
let oneArray = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];
let twoArray = [
{ "id": 0, "name": "Not Available" },
{ "id": 1, "name": "Not Ready" },
{ "id": 2, "name": "Not Started" }
];
let newArray = Object.assign([], oneArray, twoArray);
console.log(newArray);
In TS
interface Data {
oneArray: array;
twoArray: array;
}
function merge(data: Data) {
return Object.assign([], data.oneArray, data.twoArray);
}
let user = {
oneArray: [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
],
twoArray: [
{ "id": 0, "name": "Not Available" },
{ "id": 1, "name": "Not Ready" },
{ "id": 2, "name": "Not Started" }
]
};
console.log(merge(user));
Sure :)
let arrayOfObjects = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];
const newValues = ['Not Available', 'Not Ready', 'Not Started'];
newValues.forEach((value, i) => {
arrayOfObjects.find(o => o.id === i).name = value;
});
console.log(arrayOfObjects);
I wouldn't recommend this though: functional programming is awesome.
let arrayOfObjects = [
{ "id": 0, "name": "Available" },
{ "id": 1, "name": "Ready" },
{ "id": 2, "name": "Started" }
];
let names = ['Not Available', 'Not Ready', 'Not Started']
let result = arrayOfObjects.map((user, index) => ({ ...user, name: names[index] }))
console.log(result)

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)

Building new JSON from existing one

I want to build an new JSON from existing one. The source has sections and rubrics that I no longer need for a listing. The new object called 'items' should have an array of the items.
The final JSON should be sorted by attribute 'name' and look like
{
"items": [
{
"id": 10000006,
"name": "Boah"
},
{
"id": 10000013,
"name": "Gut"
},
{
"id": 10000003,
"name": "Ipsum"
},
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000002,
"name": "Stet"
}
]
}
For building the new JSON I get this source:
{
"sections": [
{
"name": "FooBar",
"rubrics": [
{
"name": "Foo",
"items": [
{
"id": 10000001,
"name": "Lorem"
},
{
"id": 10000002,
"name": "Stet"
},
{
"id": 10000003,
"name": "Ipsum"
}
]
},
{
"name": "Bar",
"items": [
{
"id": 10000004,
"name": "Name"
},
{
"id": 10000005,
"name": "Lorum"
},
{
"id": 10000006,
"name": "Boah"
}
]
}
]
},
{
"name": "BlahBloob",
"rubrics": [
{
"name": "Bla",
"items": [
{
"id": 10000013,
"name": "Gut"
}
]
},
{
"name": "Bloob",
"items": [
{
"id": 10000014,
"name": "Name"
},
{
"id": 10000015,
"name": "Lorem"
}
]
}
]
}
]
}
What do you think? How can I do this with plain JavaScript or maybe TypeScript?
Thanks for reading and have time for my question. And thanks for reply in advance.
Here you go. You just need to iterate over each rubric of each section of your source to get the items. At the end, sort your list of items by items, and you're done.
This example uses ES6 syntax, but it's easy to convert it to ES5 if needed.
function extractItems(source) {
const items = [];
for (const section of source.sections) {
for (const rubric of section.rubrics) {
items.push(...rubric.items);
}
}
items.sort((a, b) => a.name.localeCompare(b.name));
return { items };
}
A more functional approach use map and reduce to pick the rubrics and merge them.
data.sections
.map(section => section.rubrics) // get rubrics
.reduce((a, b) => a.concat(b)) // merge rubrics
.map(rubric => rubric.items) // get items from each rubric
.reduce((a, b) => a.concat(b)) // merge items
.sort((a, b) => a.name.localeCompare(b.name)); // sort
function(oldObj) {
var newObj = {
"items": []
};
oldObj.sections.forEach(function(section) {
section.rubrics.forEach(function(rubric) {
rubric.items.forEach(function(item) {
newObj.items.push(item);
});
});
});
newObj.items = newObj.items.sort(function(a, b) {
if (a.name < b.name) { return -1; }
if (a.name > b.name) { return 1; }
return 0;
});
return newObj;
}
And simply use JSON.parse() and JSON.stringify() to convert JSON to and from objects.
It might help you
var data ={
"sections": [
{
"name": "FooBar",
"rubrics": [{"name": "Foo", "items": [{"id": 10000001,"name": "Lorem"}, {"id": 10000002,"name": "Stet"}, {"id": 10000003,"name": "Ipsum"}]
}, {
"name": "Bar",
"items": [{
"id": 10000004,
"name": "Name"
}, {
"id": 10000005,
"name": "Lorum"
}, {
"id": 10000006,
"name": "Boah"
}]
}]
}, {
"name": "BlahBloob",
"rubrics": [{
"name": "Bla",
"items": [{
"id": 10000013,
"name": "Gut"
}]
}, {
"name": "Bloob",
"items": [{
"id": 10000014,
"name": "Name"
}, {
"id": 10000015,
"name": "Lorem"
}]
}]
}]
};
var itemObj = {};
var itemArr = [];
var sections = data.sections;
for(var i=0;i<sections.length;i++)
{
for(var j=0;j<sections[i].rubrics.length;j++){
for(var k=0;k<sections[i].rubrics[j].items.length;k++){
var itemObj;
itemObj['id'] = sections[i].rubrics[j].items[k].id;
itemObj['name'] = sections[i].rubrics[j].items[k].name;
itemArr.push(itemObj);
}
}
}
var finalObj = {"items":itemArr};
console.log(finalObj);
JSFiddle

Categories

Resources