I have a config.ts file with following content:
export const keyOrders: {} = {
"aa": { active: true, order: 0 },
"bb": { active: true, order: 1 },
"cc": { active: true, order: 2 },
"dd": { active: true, order: 3 },
"ee": { active: false, order: 4 },
"ff": { active: true, order: 5 }
};
I am trying to push to array if active is only true. I have tried following code which is pushing key if active is true but if active is false then it is returning "undefined"
public keys = [];
public keyOrders = keyOrders;
ngOnInit() {
this.keys = Object.entries(this.keyOrders).map((a: any) => {
if(a[1].active == 'true') {
return a[0];
}
});
}
Use filter followed by map.
If you want to sort the items based on their order property, use sort before map.
filter will only keep items passing the predicate, in this case a truthy active property. Then map will map this array to the keys.
In your case, using map will give you an array of the same length, you must filter it first.
type Order = { active: boolean, order: number };
const keyOrders: { [key: string]: Order } = {
"aa": { active: true, order: 0 },
"bb": { active: true, order: 1 },
"cc": { active: true, order: 2 },
"dd": { active: true, order: 3 },
"ee": { active: false, order: 4 },
"ff": { active: true, order: 5 }
}
this.keys = Object.entries(this.keyOrders)
.filter(([_, val]) => val.active)
.sort((a, b) => a[1].order - b[1].order)
.map(([key, _]) => key);
For the types to work out, Object.entries() must be recognized by Typescript, for this, add "lib": [ "es2017.object" ] in your tsconfig.json file.
Here is a JavaScript demo (types stripped):
const keyOrders = {
"aa": { active: true, order: 0 },
"bb": { active: true, order: 1 },
"cc": { active: true, order: 2 },
"dd": { active: true, order: 3 },
"ee": { active: false, order: 4 },
"ff": { active: true, order: 5 }
};
const keys = Object.entries(keyOrders)
.filter(([_, val]) => val.active)
.sort((a, b) => a[1].order - b[1].order)
.map(([key, _]) => key);
console.log(keys);
Related
What is the correct way to modify json response ,
My goal is to display all the MaintroomName belonging to the same Plsectn
This is the function that needs to modify to get the same structure
which I mentioned below that I am interested in reaching.
useEffect(() => {
BtpBridgeModule.loadDataFromSdk(
'GushSet',
[],
{ PlantID: userData.plant, LocationID: userData.LocationID },
undefined,
0,
).then(function (dataResolved) {
let aResults = JSON.parse(dataResolved).value;
});
}, [userData.LocationID, userData.plant]);
The json look like this :
[
{
"Maintroom":"221",
"MaintroomName":"gogi",
"Plsectn":"22",
"PlsectnName":"pardehan"
},
{
"Maintroom":"222",
"MaintroomName":"nahaleymenash",
"Plsectn":"22",
"PlsectnName":"pardehan"
},
{
"Maintroom":"231",
"MaintroomName":"gvul",
"Plsectn":"23",
"PlsectnName":"meshulash"
},
{
"Maintroom":"232",
"MaintroomName":"daro",
"Plsectn":"23",
"PlsectnName":"meshulash"
},
]
I wanna change it to this structure :
[
{
title: PlsectnName,
checked: false,
data: [
{ key: MaintroomName, value: false, checked: false },
{ key: MaintroomName, value: false, checked: false },
{ key: MaintroomName, value: false, checked: false },
{ key: MaintroomName, value: false, checked: false },
],
},
{
title: PlsectnName,
checked: false,
data: [
{ key: MaintroomName, value: false, checked: false },
{ key: MaintroomName, value: false, checked: false },
{ key: MaintroomName, value: false, checked: false },
],
},
]
Note - each Plsectn can have a dynamic number of MaintroomName.
Algorithm to sort your data
// Your response data
const data = [
{
"Maintroom":"221",
"MaintroomName":"gogi",
"Plsectn":"22",
"PlsectnName":"pardehan"
},
{
"Maintroom":"222",
"MaintroomName":"nahaleymenash",
"Plsectn":"22",
"PlsectnName":"pardehan"
},
{
"Maintroom":"231",
"MaintroomName":"gvul",
"Plsectn":"23",
"PlsectnName":"meshulash"
},
{
"Maintroom":"232",
"MaintroomName":"daro",
"Plsectn":"23",
"PlsectnName":"meshulash"
},
];
// Variable to track duplicate keys (PlsectnName)
let keys = [];
// Result after sorting the data
let result = [];
// Algorithm to sort the data
data.forEach((obj) => {
if(!keys.includes(obj.PlsectnName)){
result.push({
title: obj.PlsectnName,
checked: false,
data: [
{ key: obj.MaintroomName, value: obj.Maintroom, checked: false }
]
});
keys.push(obj.PlsectnName);
}
else {
result.forEach((subObj,index) => {
if(subObj.title == obj.PlsectnName){
subObj.data = [...subObj.data, { key: obj.MaintroomName, value: obj.Maintroom, checked: false }]
result[index] = subObj;
}
});
}
})
// Log the result
console.log(result)
(Note: If you want to set the value as false then change value: obj.Maintroom to value: false)
Implementing the Algorithm in your useEffect function.
// Algorithm as function to sort your data
const sortData = (data) => {
// Variable to track duplicate keys (PlsectnName)
let keys = [];
// Result after sorting the data
let result = [];
// Algorithm to sort the data
data.forEach((obj) => {
if(!keys.includes(obj.PlsectnName)){
result.push({
title: obj.PlsectnName,
checked: false,
data: [
{ key: obj.MaintroomName, value: obj.Maintroom, checked: false }
]
});
keys.push(obj.PlsectnName);
}
else {
result.forEach((subObj,index) => {
if(subObj.title == obj.PlsectnName){
subObj.data = [...subObj.data, { key: obj.MaintroomName, value: obj.Maintroom, checked: false }]
result[index] = subObj;
}
});
}
})
// return the result
return result;
}
// Your function
useEffect(() => {
BtpBridgeModule.loadDataFromSdk(
'GushSet',
[],
{ PlantID: userData.plant, LocationID: userData.LocationID },
undefined,
0,
).then(function (dataResolved) {
let aResults = JSON.parse(dataResolved).value;
// Added code
let sortedResult = sortData(aResults)
// Here sortedResult is your final data
});
}, [userData.LocationID, userData.plant]);
I have two arrays
const condition = [
{ iosSend: true },
{ androidSend: true }
]
const myArray = [
{
androidSend: false,
iosSend: true,
macosSend: false,
id: 1
},
{
androidSend: true,
iosSend: false,
macosSend: false,
id: 2
},
{
androidSend: true,
iosSend: true,
macosSend: false,
id: 3
},
{
androidSend: false,
iosSend: false,
macosSend: true,
id: 4
}
]
Where I want to filter myArray with the following conditions:
Return a array with objects that has at least one of the keys of object inside condition array Equals false.
I mean, in the example, the return should return an array
with objects with ids 1, 2 and 4
Which is the best way to do this?
The following is an example of filtering if you wanted all items that match any condition.
const condition = {
iosSend: false,
androidSend: false
};
const myArray = [
{
androidSend: false,
iosSend: true,
macosSend: false,
id: 1
},
{
androidSend: true,
iosSend: false,
macosSend: false,
id: 2
},
{
androidSend: true,
iosSend: true,
macosSend: false,
id: 3
},
{
androidSend: false,
iosSend: false,
macosSend: true,
id: 4
}
];
const conditions = Object.entries(condition);
const filteredArr = myArray.filter(o => {
for (const [key, val] of conditions) {
if (key in o && o[key] == val) return true;
}
return false;
});
console.log(filteredArr);
#EDIT:
I changed conditions to be either iosSend false or androidSend false after clarifying comment from author
I have an array of objects.
const people = [
{
active: true,
hasMoney: false
},
{
active: false,
hasMoney: false
},
{
active: true,
hasMoney: true
}
]
I want to sort the data in this order: active: true -> hasMoney: true -> active: false -> hasMoney: false
Important: If the user is active === true and hasMoney === true, then this should be ordered after active === true and hasMoney === false
I tried the following but it didn't work. Anyone have any ideas?
people
.sort((x, y) =>
x.hasMoney
? Number(x) - Number(y)
: Number(isPersonActive(y)) - Number(isPersonActive(x))
)
You could take the delta of the boolean values and sort by two properties with a special look to the sorting of same values.
const people = [{ active: false, hasMoney: true }, { active: true, hasMoney: false }, { active: false, hasMoney: false }, { active: true, hasMoney: true }];
people.sort((a, b) =>
b.active - a.active ||
(a.hasMoney === b.active) - (a.active === b.hasMoney)
);
console.log(people);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You can do the following,
const people = [
{
active: true,
hasMoney: true
},
{
active: false,
hasMoney: false
},
{
active: true,
hasMoney: false
}
]
people.sort((a, b) => {
if(a.active && b.active) {
return a.hasMoney - b.hasMoney;
} else if(a.active) {
return -1;
} else if(b.active) {
return 1;
} else {
return b.hasMoney - a.hasMoney;
}
})
console.log(people);
The following sort with a OR condition as per provided condition.
const people = [
{
active: true,
hasMoney: false
},
{
active: false,
hasMoney: false
},
{
active: false,
hasMoney: true
},
{
active: true,
hasMoney: false
}
];
const a = people.sort((a,b) => b.active-a.active || (b.hasMoney - a.hasMoney));
console.log(a);
const people = [
{
active: true,
hasMoney: true
},
{
active: false,
hasMoney: false
},
{
active: true,
hasMoney: false
},
{
active: false,
hasMoney: true
}
]
let peopleSorted = people.sort((a, b) => {
if (a.active == b.active) {
if (a.hasMoney < b.hasMoney) {
return 1;
} else if (a.hasMoney > b.hasMoney) {
return -1;
} else {
return 0;
}
} else if (a.active) {
return -1;
} else if (b.active) {
return 1;
} else {
return 0;
}
});
console.log(peopleSorted);
Try like this. when both are active (on campare), sort on hasMoney
const sort = (arr) => arr.sort((a, b) => {
if (a.active === b.active) {
return b.hasMoney - a.hasMoney;
}
return b.active - a.active;
})
const people = [
{
active: true,
hasMoney: false
},
{
active: false,
hasMoney: false
},
{
active: true,
hasMoney: true
}
]
const people2 = [
{ active: true, hasMoney: false },
{ active: false, hasMoney: false },
{ active: false, hasMoney: true },
{ active: true, hasMoney: true },
];
console.log(sort(people))
console.log(sort(people2))
I have a javascript variable with the following structure
var recurse = {
level_0: [
{
level_1 : [
{
level_2_0 : [
{
level_3_0: {
valid: true,
available: false
}
}, {
level_3_1 : {
valid: true,
available: true
}
}]
}, {
level_2_1 : [
{
level_3_0: {
valid: true,
available: false
}
}, {
level_3_1 : {
valid: true,
available: true
}
}]
}]
}]
}
Final required output structure
var recurse = {
name: "level_0",
property: [
{
name: "level_1",
property: [
{
name: "level_2_0",
property: [
{
name: "level_3_0",
property: {
valid: true,
available: false
}
}, {
name: "level_3_1",
property: {
valid: true,
available: true
}
}]
}, {
name: "level_2_1",
property: [
{
name: "level_3_0",
property: {
valid: true,
available: false
}
}, {
name: "level_3_1",
property: {
valid: true,
available: true
}
}]
}]
}]
}
Facing problem with cloning and updating the structure for this nested object using generic methods.
How can I achieve the required final object structure using simple javascript or reactjs properties.
Which is the most appropriate method to clone a javascript object?
Note: the object names- level_0, level_1 level_2_0 could be random or dynamic.
You can write a simple recursive function that recurses on the item if the item value is an array like below
var recurse = {
level_0: [
{
level_1 : [
{
level_2_0 : [
{
level_3_0: {
valid: true,
available: false
}
}, {
level_3_1 : {
valid: true,
available: true
}
}]
}, {
level_2_1 : [
{
level_3_0: {
valid: true,
available: false
}
}, {
level_3_1 : {
valid: true,
available: true
}
}]
}]
}]
}
function format(data) {
return Object.entries(data).map(([key, value]) => {
if(Array.isArray(value))
return {
name: key,
property: [].concat(...value.map(item => format(item)))
}
return {
name: key,
property: value
}
})
}
console.log(format(recurse));
You can transform it with something like this:
const transform = (tree) =>
Object (tree) === tree
? Object .entries (tree) .map (([name, properties]) => ({
name,
properties: Array .isArray (properties) ? properties .map (transform) : properties
})) [0] // This is a strage thing to do with an object! The original data structure is odd.
: tree
var recurse = {level_0: [{level_1: [{level_2_0: [{level_3_0: {valid: true, available: false}}, {level_3_1: {valid: true, available: true}}]}, {level_2_1: [{level_3_0: {valid: true, available: false}}, {level_3_1: {valid: true, available: true}}]}]}]}
console .log (transform (recurse))
.as-console-wrapper {min-height: 100% !important; top: 0}
But the data structure you start with is quite odd. Each level of nesting except the innermost can only have a single property. Is that really how your data comes to you? It's a strange use of objects. (Then again, you are asking about how to reforat it...)
The [0] on the sixth line of the above deals with that oddity of the input.
I am having a hard time trying to convert an object supplied in a specific format from API into a target format using javascript. Please note that in the target format, the false values are not present. This is intentional. Can someone please help by showing how I can do the this kind of conversion. Thank you
// Original format
const rules= [
{
dealer: {
view: true,
edit: false,
add: false
},
franchise: {
view: true,
edit: true,
add: true
},
branch: {
view: true,
edit: false,
add: false
}
}
]
// Target format
const rules = [
{
actions: ["view"],
subject: ["dealer"]
},
{
actions: ["view"],
subject: ["franchise"]
},
{
actions: ["edit"],
subject: ["franchise"]
},
{
actions: ["add"],
subject: ["franchise"]
},
{
actions: ["view"],
subject: ["branch"]
}
];
I implemented mapping function which take each item and map it according to the value if true
let rules = [
{
dealer: {
view: true,
edit: false,
add: false
},
franchise: {
view: true,
edit: true,
add: true
},
branch: {
view: true,
edit: false,
add: false
}
}
]
rules = rules.map(item => {
const keys = Object.keys(item);
let mappedItem = []
keys.forEach(key => {
for (const property in item[key]) {
if (item[key][property]) {
mappedItem.push({ subject: [key], actions: [property] })
}
}
})
return mappedItem;
});
let rules= [
{
dealer: {
view: true,
edit: false,
add: false
},
franchise: {
view: true,
edit: true,
add: true
},
branch: {
view: true,
edit: false,
add: false
}
}
];
const result = rules.map(obj => Object.keys(obj).map(k => ({
subject: [k],
actions: Object.keys(obj[k]).filter(action => obj[k][action])
})).reduce((acc, cur) => ([
...acc,
...cur.actions.map(a => ({subject: cur.subject, actions: [a]}))
]),[]))
console.log(result);