How can I pass object keys into an array that are true. So that I can use this array for filtering?
Example Object:
let results = [
{name: marc, isAlumnus: true, isScholar: true, isTrustee: false},
{name: franz, isAlumnus: false, isScholar: true, isTrustee: false},
{name: Hugo, isAlumnus: true, isScholar: true, isTrustee: false},
]
And the attempt of a function!
getActiveStatusGroups (results) {
let res = [];
res = results.map((item) => {
if (item) {
res.push('isScholar');
}
});
return res;
},
let statusArray = getActiveStatusGroup(this.results)
You can get an array of the property names from Object.keys, or an array of [name, value] arrays from Object.entries, depending on what you want to do.
It's kind of hard to tell what output you want as a result, but for instance, this returns an array of arrays, where the inner arrays are the names of the properties for which the value was truthy:
getActiveStatusGroups(results) {
return results.map(entry =>
Object.keys(entry).filter(key => entry[key])
);
}
Live Example:
let results = [
{isAlumnus: true, isScholar: true, isTrustee: false},
{isAlumnus: false, isScholar: true, isTrustee: false},
{isAlumnus: true, isScholar: true, isTrustee: false},
];
function getActiveStatusGroups(results) {
return results.map(entry =>
Object.keys(entry).filter(key => entry[key])
);
}
console.log(getActiveStatusGroups(results));
Filtering is pretty simple in JavaScript
The methods name is right there in your title, yet you failed to recognize it. Use filter instead of map. The filter() method creates a new array with all elements that pass the test implemented by the provided function.
Here's your code
let results = [
{name: marc, isAlumnus: true, isScholar: true, isTrustee: false},
{name: franz, isAlumnus: false, isScholar: true, isTrustee: false},
{name: Hugo, isAlumnus: true, isScholar: true, isTrustee: false},
]
getActiveStatusGroups(group) {
// returns the element if the condition is true
return results.filter(result => result[group])
}
That's it
console.log(getActiveStatusGroups('isAlumnus'))
console.log(getActiveStatusGroups('isScholar'))
console.log(getActiveStatusGroups('isTrustee'))
Related
I am allowing my users to create different roles for themselves within my svelteKit application.
I have a text input with a button that adds that value to an array and shows in the div below.
I need to convert the array into a tiered JSON object so I can add it to my Postgres database role_permissions column as JSONB. I have tried JSON.stringify() and JSON.parse() but I cannot get it to work.
Ideally formatted like this:
{
"role_name"{
"permission": true,
"permission": true,
...
}
"role_name_2"{
"permission": true,
"permission": false,
...
}
}
While my users can create roles with custom names the permissions available are all the same e.g.:
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
can_delete_roles: false,
can_edit_roles: false,
can_assign_roles: false,
can_create_projects: false,
can_delete_projects: false,
can_edit_projects: false,
can_publish_projects: false,
can_view_projects: false,
can_assign_members_to_projects: false,
I can't figure out how to convert the object into a tiered JSON format. I know I need some sort of key outside of each object but I do not know how to do that.
This is how they appear in console.log()
{name: "Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
{name: "Associate Partner", can_add_members: false, can_delete_members: false, can_edit_members: false, can_create_roles: false, …}
The actual code:
let newItem = '';
// An array of the roles names that will also be saved to the database as is.
let roleList = [];
// The array that needs to be converted to JSON
let roleListWithPermissions = [],
function addToList() {
roleList = [...roleList, {text: newItem,}];
roleListWithPermissions = [...roleListWithPermissions, {
"name": newItem,
"can_add_members": false,
"can_delete_members": false,
"can_edit_members": false,
"can_create_roles": false,
"can_delete_roles": false,
"can_edit_roles": false,
"can_assign_roles": false,
"can_create_projects": false,
"can_delete_projects": false,
"can_edit_projects": false,
"can_publish_projects": false,
"can_view_projects": false,
"can_assign_members_to_projects": false
}];
newItem = '';
console.log("ROLE LIST",roleList)
console.log("PERMISSIONS LIST",roleListWithPermissions)
}
One approach is below, with explanatory comments in the code:
// the original Object as described/shown in the question:
let source = [{
name: "Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
},
{
name: "Associate Partner",
can_add_members: false,
can_delete_members: false,
can_edit_members: false,
can_create_roles: false,
}
],
// here we use Array.prototype.map() to iterate over the Array of Objects:
rolePermissions = source.map(
// using destructuring assignment to retrieve the 'name'
// property from the Array-element (the Object),
// and assigning all remaining property-value pairs
// to the 'rest' variable:
({
name,
...rest
}) => {
// here we return a new Object, with the computed value of the
// 'name' variable to set the property equal to the value of the
// variable rather than the String of 'name':
return {
// and the property-value equal to the Object containing the
// rest of the key-value pairs:
[name]: rest
};
}),
// converting the Array of Objects into a JSON string:
jsonRolePermissions = JSON.stringify(rolePermissions);
// logging that JSON string to the console:
console.log(jsonRolePermissions);
Reference:
Array.prototype.map().
Destructuring assignment.
JSON.stringify().
Object initializer.
you can transform roleListWithPermissions array to an object.
const finalResult =
roleListWithPermissions.reduce((result, current) => {
result[current.name]= {...current};
delete result[current.name].name;
return result;
}, {})
There's about million questions (and answers) out there on this topic, but none of them are doing what I need to do. I have a JSON object where the value for each key is an object. I want to convert this to an array and maintain the top level keys.
{
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
}
If I use Object.keys() I get the top level keys, but not their values. If I use Object.values() I get an array with all the values, but not their keys. I'm trying to use keys and map, but am only getting the values returned:
const data = {
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
}
const items = Object.keys(data).map(function(key) {
return data[key];
});
// returns [{active: true, name: foo},{active: false, name: bar}]
Is there a way to get both? I want to get an array I can iterate over that looks something like this:
[{
key: someKey1,
active: true,
name: "foo"
},
{
key: someKey2,
active: true,
name: "foo"
}]
OR
[
"someKey1": {
active: true,
name: "foo"
},
"someKey2": {
active: false,
name: "bar"
}
]
I think you are going in the right direction, if you want to add the "key" property you have to map the properties manually and for the second option since you don't need the "key" property it can be done a little bit more elegantly:
For the first option:
Object.keys(data).map(v => ({
key: v,
...data[v]
}));
For the second option even simpler:
Object.keys(data).map(v => ({[v]: {...data[v]}}))
You can easily map your data to a new object:
Object.keys(data).map(key => ({ ...data[key], "key": key }));
Let's say I have array of objects - original items
originalItems = [
{name:"aaa", expanded: false, visible: true},
{name:"bbb", expanded: false, visible: true},
{name:"ccc", expanded: false, visible: true}
]
then I do some changes on items
currentItems = [
{name:"aaa", expanded: true, visible: false},
{name:"bbb", expanded: false, visible: true},
{name:"ccc", expanded: true, visible: true}
]
Now I need to merge those two arrays,
BUT: in the merged arrays (result), I need that expanded value will be from currentItems, and visible will be from originalItems
something like this
result = [
{name:"aaa", expanded: true, visible: true},
{name:"bbb", expanded: false, visible: true},
{name:"ccc", expanded: true, visible: true}
]
Is there some elegant way to achieve it? Or just go through properties?
You can use .map() on one of the arrays, for example the original one, and transform each object into a new object by spreading the properties of the original object (...) into a new object. You can then set the expanded property to take the value from its corresponding object in the currentItems via the index (i). See example below:
const originalItems = [ {name:"aaa", expanded: false, visible: true}, {name:"bbb", expanded: false, visible: true}, {name:"ccc", expanded: false, visible: true} ];
const currentItems = [ {name:"aaa", expanded: true, visible: false}, {name:"bbb", expanded: false, visible: true}, {name:"ccc", expanded: true, visible: true} ];
const res = originalItems.map((obj, i) => ({
...obj,
expanded: currentItems[i].expanded
}));
console.log(res);
I'd sort and manage arrays like this, for simplicity as well speed. Perhaps more on par with what you were looking to do.
let Items = [
{ name: "aaa", expanded: false, visible: true },
{ name: "bbb", expanded: false, visible: true },
{ name: "ccc", expanded: false, visible: true }
]
function doExpand(name, val) {
let item = getItem(name);
item.expanded = val;
}
function doVisible(name, val) {
let item = getItem(name);
item.visible = val;
}
function addItem(name) {
if (!getItem(name)) {
Items.push({ name: name, expanded: false, visible: false });
} else {
console.log("duplicates found");
}
}
function getItem(name) {
for (let i = 0; i < Items.length; i++) {
if (Items[i].name === name) return Items[i];
}
return false;
}
/* TESTING TIME */
doExpand("aaa", true);
doExpand("aaa", false);
let Item = getItem("bbb");
Item.name = "renamed";
addItem("dogsnacks");
addItem("bacon");
addItem("programming");
addItem("programming");
addItem("programming");
addItem("programming");
addItem("programming");
console.log(Items);
Since you're taking the elements from two different arrays of the same length to create a third, you can create a new array, then loop through the number of objects in the array, constructing your result object based on the desired source list.
let result = [];
for (i = 0; i < originalItems.length; i++) {
let newObj = {
name: originalItems[i].name,
expanded: currentItems[i].expanded,
visible: originalItems[i].visible,
};
result.push(newObj);
}
What is the best way for me to filter through the below columns array of objects, select the correct object using my switch method, and set the show property to false (JavaScript)? This is the first time implementing something like this, and I am a a bit uncertain how to tackle this.
Example: if I pass 'Surname' to my showHideSelectedColumn(column) method, it filters the columns array, finds the {name: 'Surname', show: true} object, and sets this specific object's show property to false.
columns = [{name: 'Surname', show: true}, {name: 'Name', show: false}, {name: 'Gender', show: true}, {name: 'Date of Birth', show: false}, {name: 'ID/Passport Number', show: true}, {name: 'Membership Status', show: true}];
showHideSelectedColumn(column) {
switch (column) {
case 'Surname':
// set show = false
break;
case 'Name':
// set show = false
break;
case 'Gender':
// set show = false
break;
case 'Date of Birth':
// set show = false;
break;
case 'ID/Passport Number':
// set show = false
break;
}
Aternative and generic solution using .find method . You need to pass the array and the column name to the method , it will return you the updated array setting show property of that column to be false
var columns = [{name: 'Surname', show: true}, {name: 'Name', show: false}, {name: 'Gender', show: true}, {name: 'Date of Birth', show: false}, {name: 'ID/Passport Number', show: true}, {name: 'Membership Status', show: true}];
function setShow(array, column){
var found = array.find(obj => obj.name===column);
if(found){
found.show = false;
}
return array;
}
console.log(setShow(columns,"Surname"))
Hi you can map your array and if there is match you can toggle it by following example
Array.prototype.toggleProperty = function (property){
return this.map(el=>{
if(el.name===property){
return {...el,show:!el.show}
}
else{
return el
}
})
}
// test
console.log(columns.toggleProperty("Name"))
I use firebase and I am creating a follow system which pushes in firebase my data like that when I follow:
firebase.database().ref('followers/' + followedId).update({ [this.userId]: true });
firebase.database().ref('followings/' + this.userId).update({ [followedId]: true });
Then If I would like to display my list of followers / followings, I need an array of object {followedId: true}
I need to change the format of the result [{followedId: true}] to an array of followedId. Hope is more clear.
If your results look like {uid1: true, uid2: true, uid3: true, uid4: true}
const results = {uid1: true, uid2: true, uid3: true, uid4: true}
const followers = Object.keys(results)
console.log(followers) // ["uid1", "uid2", "uid3", "uid4"]
If you need them formatted as per your comment:
const results = {uid1: true, uid2: true, uid3: true, uid4: true}
const followers = Object.keys(results).map(id => ({ uid: id, checked: true }))
console.log(followers)