I have a JavaScript array with the following format:
[
{
"header": true,
"id": "0",
"name": "dairy",
},
{
"category": "dairy",
"header": false,
"id": "-LSlje6ESGALGpckMhb7",
"name": "milk",
},
{
"category": "dairy",
"header": false,
"id": "-LSm9EpFg5DhW036aUle",
"name": "cheese",
},
{
"header": true,
"id": "3",
"name": "dessert",
},
{
"category": "dessert",
"header": false,
"id": "-LSm9MLZkrnvtPySw5U6",
"name": "cake",
},
{
"category": "dessert",
"header": false,
"id": "-LSmAQ0rdDLrpz0TSPuD",
"name": "pie",
},
{
"header": true,
"id": "6",
"name": "fruit",
},
{
"category": "fruit",
"header": false,
"id": "-LSlazVIGAKLakxAIa8G",
"name": "apple",
},
{
"category": "fruit",
"header": false,
"id": "-LSlb5GH6xZz-DpNVS22",
"name": "pear",
},
{
"category": "fruit",
"header": false,
"id": "-LSwWJldY1nxQrotyv-V",
"name": "strawberry",
},
{
"header": true,
"id": "10",
"name": "meat",
},
{
"category": "meat",
"header": false,
"id": "-LSljXQzfXthJbOA54Ah",
"name": "fish",
},
{
"category": "meat",
"header": false,
"id": "-LSmA2-R9pOY8abAUyST",
"name": "steak",
},
{
"category": "meat",
"header": false,
"id": "-LSmAJ4J4gIfVQ8sgPDa",
"name": "pork",
},
]
What I am trying to do, is map through this array, and transform it to the following format:
[
{
title: nameOfFirstHeader,
data: items.slice(indexOfFirstHeader, indexOfSecondHeader),
},
{
title: nameOfSecondHeader,
data: items.slice(indexOfSecondHeader, indexOfThirdHeader),
},
{
title: nameOfThirdHeader,
data: items.slice(indexOfThirdHeader, indexOfFourthHeader),
},...and so on
]
So basically there will be an object section for each 'header' that is found in the original array. Each object section data property will contain the items found between the first header and the second header, and so on, until there are no more headers. I really can't wrap my head around how I can do this. Here is a reference to the the module I am using: https://github.com/saleel/react-native-super-grid#sectiongrid-example
Thanks!
I think this may be what you're trying to accomplish...
var grouped = items.reduce((acc,obj)=>{
let {header, name} = obj;
if (header) return [...acc, { title:name, data:[] }] // either first matching header or new match. Add fresh 'header' object
if (!acc.length) return acc; //not header and none have passed. Do nothing
let allButLast = acc.slice(0, acc.length-1),
lastElem = acc[acc.length-1]; // not a header, but there is an existing match. Add it to last match's data array
return [
...allButLast,
{
...lastElem,
data:[...lastElem.data, obj]
}
]
},[])
but it seems unreliable to trust the order of an array for this purpose. It would probably be more reliable to match by isHeader.name === notHeader.category to be less presumptive about the order of data you're iterating over. Like this...
var grouped = items.reduce((acc,obj)=>{
let {header, name, category} = obj;
if (header) return [...acc, { title:name, data:[] }];
if (!acc.length) return acc;
return acc.map((elem)=>{
if (elem.title !== category) return elem;
return {
...elem,
data: [ ...elem.data, obj]
};
})
},[])
I think you can probably do something like
const data = [];
let activeIndexForData = -1;
for(let i = 0; i < dataToSort.length -1; i++) {
if(dataToSort[i].header) {
activeIndexForData++;
}
if(data.length < activeIndexForData - 1) {
data.push({ title: dataToSort[i].name, data# []})
}
else {
data[activeIndexForData].data.push({ title: dataToSort[i].name, data: [])
}
}
Related
I have an array of object and another object containing labels, how to write a simple function to compare both array and replace the key name.
input = [
{
"id": "AAP",
"prd": "PL",
"trcode": "NORTH",
"accountNo": "12345",
"prBranch": null,
"prDealer": "Dealer 1",
"prUser": "CFG",
"staticBranch": "YES",
"staticCustomer": "NO",
"reason": "Invalid request"
},
{
"id": "AAC",
"prd": "PL",
"trcode": "WEST",
"accountNo": "67890",
"prBranch": null,
"prDealer": "Dealer 2",
"prUser": "DFG",
"staticBranch": "YES",
"staticCustomer": "NO",
"reason": "Invalid request"
}
],
labels = [
{
"key": "id",
"value": "USER"
},
{
"key": "prd",
"value": "PRODUCT"
},
{
"key": "trcode",
"value": "TRANSFER_CODE"
},
{
"key": "accountNo",
"value": "ACCOUNT_NUMBER"
},
{
"key": "prBranch",
"value": "PROCESSING_BRANCH"
},
{
"key": "prDealer",
"value": "PROCESSING_DEALER"
},
{
"key": "prUser",
"value": "PROCESSING_USER"
},
{
"key": "staticBranch",
"value": "STATIC_BRANCH"
},
{
"key": "staticAgent",
"value": "STATIC_AGENT"
},
{
"key": "reason",
"value": "Reason"
}
]
Expected output =
[
{
"USER": "AAP",
"PRODUCT": "PL",
"TRANSFER_CODE": "NORTH",
"ACCOUNT_NUMBER": "12345",
"PROCESSING_BRANCH": null,
"PROCESSING_DEALER": "Dealer 1",
"PROCESSING_USER": "CFG",
"STATIC_BRANCH": "YES",
"STATIC_CUSTOMER": "NO",
"Reason": "Invalid request"
},
{
"USER": "AAC",
"PRODUCT": "PL",
"TRANSFER_CODE": "WEST",
"ACCOUNT_NUMBER": "67890",
"PROCESSING_BRANCH": null,
"PROCESSING_DEALER": "Dealer 2",
"PROCESSING_USER": "DFG",
"STATIC_BRANCH": "YES",
"STATIC_CUSTOMER": "NO",
"Reason": "Invalid request"
}
],
You can use Array#map to convert each object in the array. For each object, we can map over the entries of the object and use Array#find to look for the replacement key if it exists. Finally, Object.fromEntries converts the array of key-value pairs back to an object.
let input=[{id:"AAP",prd:"PL",trcode:"NORTH",accountNo:"12345",prBranch:null,prDealer:"Dealer 1",prUser:"CFG",staticBranch:"YES",staticCustomer:"NO",reason:"Invalid request"},{id:"AAC",prd:"PL",trcode:"WEST",accountNo:"67890",prBranch:null,prDealer:"Dealer 2",prUser:"DFG",staticBranch:"YES",staticCustomer:"NO",reason:"Invalid request"}],labels=[{key:"id",value:"USER"},{key:"prd",value:"PRODUCT"},{key:"trcode",value:"TRANSFER_CODE"},{key:"accountNo",value:"ACCOUNT_NUMBER"},{key:"prBranch",value:"PROCESSING_BRANCH"},{key:"prDealer",value:"PROCESSING_DEALER"},{key:"prUser",value:"PROCESSING_USER"},{key:"staticBranch",value:"STATIC_BRANCH"},{key:"staticAgent",value:"STATIC_AGENT"},{key:"reason",value:"Reason"}];
const res = input.map(o =>
Object.fromEntries(Object.entries(o)
.map(([k,v])=>[labels.find(({key})=>key===k)?.value ?? k, v])));
console.log(res)
.as-console-wrapper{max-height:100%!important;top:0}
Loop through input and inside the loop use a for...in loop to loop through each property.
Inside the loop, loop through labels and get the corresponding value to that property, set the value of the property to the new property and delete the previous property.
input.forEach(e => {
for (const l in e) {
var a;
labels.forEach(e => {
e.key == l && (a = e.value)
}), e[a] = e[l], delete e[l]
}
});
Demo:
input=[{id:"AAP",prd:"PL",trcode:"NORTH",accountNo:"12345",prBranch:null,prDealer:"Dealer 1",prUser:"CFG",staticBranch:"YES",staticCustomer:"NO",reason:"Invalid request"},{id:"AAC",prd:"PL",trcode:"WEST",accountNo:"67890",prBranch:null,prDealer:"Dealer 2",prUser:"DFG",staticBranch:"YES",staticCustomer:"NO",reason:"Invalid request"}];var labels=[{key:"id",value:"USER"},{key:"prd",value:"PRODUCT"},{key:"trcode",value:"TRANSFER_CODE"},{key:"accountNo",value:"ACCOUNT_NUMBER"},{key:"prBranch",value:"PROCESSING_BRANCH"},{key:"prDealer",value:"PROCESSING_DEALER"},{key:"prUser",value:"PROCESSING_USER"},{key:"staticBranch",value:"STATIC_BRANCH"},{key:"staticAgent",value:"STATIC_AGENT"},{key:"reason",value:"Reason"}];
input.forEach(e=>{for(const l in e){var a;labels.forEach(e=>{e.key==l&&(a=e.value)}),e[a]=e[l],delete e[l]}});
console.log(input);
One of the first thing I would to is to use an object instead of an array for your key association:
labels = {
"id": "USER",
"prd": "PRODUCT",
"trcode": "TRANSFER_CODE",
"accountNo": "ACCOUNT_NUMBER",
"prBranch": "PROCESSING_BRANCH",
"prDealer": "PROCESSING_DEALER",
"prUser": "PROCESSING_USER",
"staticBranch": "STATIC_BRANCH",
"staticAgent": "STATIC_AGENT",
"reason": "Reason"
}
Now if you want to map them to your new object you can do
function renameKeys(src) {
let entries = Object.entries(src)
let renamedEntries = entries.map(([key, value]) => [
labels[key] || key,
/* I added a fallback to the original key
if it's not found to avoid undefined keys */
value,
])
return Object.fromEntries(renamedEntries)
}
// and use it like so
console.log(input.map(renameKeys))
You can just iterate them and assign the values as below
for (var object of input) {
for (var mapping of labels) {
if (object[mapping.key] !== undefined) {
object[mapping.value] = object[mapping.key];
delete object[mapping.key];
}
}
}
console.log(input);
The way I'd do it would be:
const input = [{
"id": "AAP",
"prd": "PL",
"trcode": "NORTH",
"accountNo": "12345",
"prBranch": null,
"prDealer": "Dealer 1",
"prUser": "CFG",
"staticBranch": "YES",
"staticCustomer": "NO",
"reason": "Invalid request"
},
{
"id": "AAC",
"prd": "PL",
"trcode": "WEST",
"accountNo": "67890",
"prBranch": null,
"prDealer": "Dealer 2",
"prUser": "DFG",
"staticBranch": "YES",
"staticCustomer": "NO",
"reason": "Invalid request"
}
];
const labels = [{
"key": "id",
"value": "USER"
},
{
"key": "prd",
"value": "PRODUCT"
},
{
"key": "trcode",
"value": "TRANSFER_CODE"
},
{
"key": "accountNo",
"value": "ACCOUNT_NUMBER"
},
{
"key": "prBranch",
"value": "PROCESSING_BRANCH"
},
{
"key": "prDealer",
"value": "PROCESSING_DEALER"
},
{
"key": "prUser",
"value": "PROCESSING_USER"
},
{
"key": "staticBranch",
"value": "STATIC_BRANCH"
},
{
"key": "staticAgent",
"value": "STATIC_AGENT"
},
{
"key": "reason",
"value": "Reason"
}
]
// 1. create an object mapping the old labels to the new ones
const betterLabels = labels.reduce((outObj, item) => {
outObj[item.key] = item.value;
return outObj;
}, {});
// 2. use `Array.prototype.map` to traverse the input array
// and `Array.prototype.reduce` with the label mapping object
// to generate the output array
const output = input.map(item => {
return Object.entries(item).reduce((newItem, [key, value]) => {
betterLabels[key]
? newItem[betterLabels[key]] = value
: newItem[key] = value
return newItem
}, {});
});
//test
console.log(output);
I have an object like this :
{
"roleId": "75f6af0f-a483-4ad1-af5f-5802887fe5e6",
"roleClaims": [
{
"type": "Permissions",
"value": "Permissions.Brands.View",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Brands.Create",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Dashboard.Create",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Users.Create",
"selected": false
}
]
}
I want to re-organize the roleClaims array [ like each unique types objects (value = "Permissions.Brands.View" > Brands ) are separated array ] as mentioned below. And additionally add an extra property checkboxId (which value is unique number) to filtered object from the array of objects.
Is is really possible?
{
"roleId": "75f6af0f-a483-4ad1-af5f-5802887fe5e6",
"roleClaims": [
{
"valueId": "a8ca7eac-4f18-42d6-983f-44f6a8e157dc",
"valueType": "Brands",
"valueArray": [
{
"checkboxId": uuidv4(), // create new unique id
"type": "Permissions",
"value": "Permissions.Brands.View",
"selected": false
},
{
"checkboxId": uuidv4(),,
"type": "Permissions",
"value": "Permissions.Brands.Create",
"selected": false
}
]
},
{
"valueId": "a2566fd4-8763-41d4-881e-029851a440fd",
"valueType": "Dashboard",
"valueArray": [
{
"checkboxId": uuidv4(),,
"type": "Permissions",
"value": "Permissions.Dashboard.Create",
"selected": false
}
]
},
{
"valueId": "72328955-2bd2-469c-a094-be0bba383edd",
"valueType": "Users",
"valueArray": [
{
"checkboxId": uuidv4(),,
"type": "Permissions",
"value": "Permissions.Users.Create",
"selected": false
}
]
}
]
}
I tried with this :
const getRoleDetailsByRoleId = roleId => {
axios.get(`${urls.account.permissions.get_all_by_roleId}?roleId=${roleId}`).then(res => {
const permissionData = res.data;
const splitedValues = [];
permissionData.roleClaims.forEach(item => splitedValues.push(item.value.split('.')[1]));
const uniqueValues = [...new Set(splitedValues)];
const modifiePermissiondObj = {
roleId: permissionData.roleId,
roleClaims: uniqueValues.map(item => ({
valueId: uuidv4(),
valueType: item,
valueArray: permissionData.roleClaims.filter((fileredItem, index, arr) => fileredItem.value.split('.')[1] === item)
}))
};
setPermissions(modifiePermissiondObj);
setIsPageLoaded(true);
});
};
I have modified the roleClaims array but can't add the additional property.
If possible please help me.
const permissionData = {
"roleId": "75f6af0f-a483-4ad1-af5f-5802887fe5e6",
"roleClaims": [
{
"type": "Permissions",
"value": "Permissions.Brands.View",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Brands.Create",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Dashboard.Create",
"selected": false
},
{
"type": "Permissions",
"value": "Permissions.Users.Create",
"selected": false
}
]
}
const transformedPermissionData = permissionData.roleClaims.reduce((newOutput, role) => {
const extractedRole = role.value.split('.')[1];
const roleIndex = newOutput.roleClaims.findIndex(output => output && output.valueType === extractedRole)
if(roleIndex !== -1){
newOutput.roleClaims[roleIndex].valueArray.push({...role, checkboxId: 'UUID'})
}else {
newOutput.roleClaims.push({
valueId: 'UUID',
valueType: extractedRole,
valueArray: [{...role, checkboxId: 'UUID'}]
})
}
return newOutput
}, { roleId: permissionData.roleId, roleClaims: []})
console.log(transformedPermissionData)
You just need to map your valueArray like this:
valueArray: permissionData.roleClaims
.filter((fileredItem, index, arr) => fileredItem.value.split('.')[1] === item)
.map(value => ({...value, checkboxId: uuidv4()}))
I have an object that looks like the following {key: id numbers}
var obj = {
"c4ecb": {id: [3]},
"a4269": {id: [34,36]},
"d76fa": {id: [54,55,60,61]},
"58cb5": {id: [67]}
}
How do I loop each above id in the following array, and return the label?
var response =
{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}
Finally, what I want to do is look up the key and return a string of id values.
For example, input c4ecb and output strawberry. Input a4269 and output lettuce, radish. Input d76fa and output "spaghetti, rigatoni, lasagna, fettuccine"
I think to join the multiple labels output into one string I could use something like
array.data.vegetables.map(vegetables => vegetables.value).join(', ')].toString();
So in the end I want to have something like
var fruits = [some code that outputs "strawberry"];
var vegetables = [some code that outputs "lettuce, radish"];
var pasta = [some code that outputs "spaghetti, rigatoni, lasagna, fettuccine"];
What I've tried so far:
The following loop will return the id only if there is one id to be called for: e.g. only in case one where {id: 3} but returns null in cases like {id: 34,36} (because it's looking for '34,36' in id, which doesn't exist - I need to look for each one individually.
response.data.forEach(({key, options}) => {
if (obj[key]) {
options.forEach(({id, label}) => {
if (id == obj[key].id) obj[key].label = label;
});
}
});
console.log(obj)
Filter the response object to focus on the category that matches the id.
Map over the options array and select the items which appear in obj[id].
Finally convert the filtered results to a string.
See filteredLabelsAsString() function below for implementation.
var obj = {
"c4ecb": {"id": [3]},
"a4269": {"id": [34,36]},
"d76fa": {"id": [54,55,60,61]},
"58cb5": {"id": [67]}
}
var response =
[{
"success": true,
"data": [
{
"key": "c4ecb",
"name": "fruits",
"options": [
{
"label": "strawberry",
"id": 3
},
{
"label": "apple",
"id": 4
},
{
"label": "pineapple",
"id": 5
},
{
"label": "Other",
"id": 31
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "a4269",
"name": "vegetables",
"options": [
{
"label": "lettuce",
"id": 34
},
{
"label": "cucumber",
"id": 35
},
{
"label": "radish",
"id": 36
}
],
}
]
},
{
"success": true,
"data": [
{
"key": "d76fa",
"name": "pasta",
"options": [
{
"label": "spaghetti",
"id": 54
},
{
"label": "rigatoni",
"id": 55
},
{
"label": "linguine",
"id": 56
},
{
"label": "lasagna",
"id": 60
},
{
"label": "fettuccine",
"id": 61
}
],
}
]
}];
function filteredLabelsAsString(obj_key, obj, content=response) {
// sanity check: obj must contain obj_key
if (Object.keys(obj).includes(obj_key)) {
return content.filter((item) => {
// filter content using value of obj_key
return item.data[0].key == obj_key;
}).map((item) => {
// item : { success: true, data: [] }
// map over options array
return item.data[0].options.map((opt) => {
// option : {id, label}
// return the label if the id is in the obj object's list
if (obj[item.data[0].key].id.includes(opt.id))
return opt.label;
}).filter((label) => {
// filter out empty items
return label !== undefined;
});
}).join(",");
}
// if obj does not contain obj_key return empty string
return "";
}
console.log("fruits: " + filteredLabelsAsString("c4ecb", obj));
console.log("vegetables: " + filteredLabelsAsString("a4269", obj));
console.log("pasta: " + filteredLabelsAsString("d76fa", obj));
Check for the decimal id and group them accordingly.
Below are the sample and recommended JSON's
Sample JSON
{
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
Would like to iterate and Re-structure the above JSON into below recommended format.
Logic: Should check the id(with and without decimals) and group them based on the number.
For Example:
1, 1.1, 1.2.3, 1.4.5 => data1: [{id: 1},{id: 1.1}....]
2, 2.3, 2.3.4 => data2: [{id: 2},{id: 2.3}....]
3, 3.1 => data3: [{id: 3},{id: 3.1}]
Recommended JSON
{
"results": [
{
"data1": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
}
]
},
{
"data2": [
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
}
]
},
{
"data3": [
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
}
]
},
{
"data4": [
{
"name": "Download",
"id": "4.2"
}
]
}
]
}
I have tried the below solution but it doesn't group the object
var formatedJSON = [];
results.map(function(d,i) {
formatedJSON.push({
[data+i]: d
})
});
Thanks in advance.
You can use reduce like this. The idea is to create a key-value pair for each data1, data2 etc so that values in this object are the values you need in the final array. Then use Object.values to get those as an array.
const sampleJson = {"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]}
const grouped = sampleJson.results.reduce((a, v) => {
const key = `data${parseInt(v.id)}`;
(a[key] = a[key] || {[key]: []})[key].push(v);
return a;
},{});
console.log({results: Object.values(grouped)})
One liner / Code-golf:
let s={"results":[{"name":"Download","id":"1.1.1"},{"name":"Download","id":"1.2"},{"name":"Download","id":"1.3.2"},{"name":"Download","id":"2"},{"name":"Download","id":"2.3"},{"name":"Download","id":"3.2"},{"name":"Download","id":"3.5"},{"name":"Download","id":"4.2"}]},k;
console.log({results:Object.values(s.results.reduce((a,v)=>(k=`data${parseInt(v.id)}`,(a[k] = a[k]||{[k]:[]})[k].push(v),a),{}))})
Here you go:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
let newSet = new Set();
data.results.forEach(e => {
let key = e.id.substring(0, e.id.indexOf('.'));
console.log(key);
if (newSet.has(key) == false) {
newSet.add(key);
newSet[key] = [];
}
newSet[key].push(e.id);
});
console.log(newSet);
Here's how you'd do it:
var data = {
"results": [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
};
var newData = {
"results": {}
};
data.results.forEach(item => {
var num = item.id.slice(0, 1);
if (newData.results["data" + num]) {
newData.results["data" + num].push(item);
} else {
newData.results["data" + num] = [item];
}
})
data = newData;
console.log(data);
What this does is it iterates through each item in results, gets the number at the front of this item's id, and checks if an array of the name data-{num} exists. If the array exists, it's pushed. If it doesn't exist, it's created with the item.
let input = getInput();
let output = input.reduce((acc, curr)=>{
let {id} = curr;
let majorVersion = 'name' + id.split('.')[0];
if(!acc[majorVersion]) acc[majorVersion]= [];
acc[majorVersion].push(curr);
return acc;
},{})
console.log(output)
function getInput(){
return [
{
"name": "Download",
"id": "1.1.1"
},
{
"name": "Download",
"id": "1.2"
},
{
"name": "Download",
"id": "1.3.2"
},
{
"name": "Download",
"id": "2"
},
{
"name": "Download",
"id": "2.3"
},
{
"name": "Download",
"id": "3.2"
},
{
"name": "Download",
"id": "3.5"
},
{
"name": "Download",
"id": "4.2"
}
]
}
One solution with RegEx for finer control as it would differentiate easily between 1 and 11.
Also this will make sure that even if the same version comes in end(say 1.9 in end) it will put it back in data1.
let newArr2 = ({ results }) =>
results.reduce((acc, item) => {
let key = "data" + /^(\d+)\.?.*/.exec(item.id)[1];
let found = acc.find(i => key in i);
found ? found[key].push(item) : acc.push({ [key]: [item] });
return acc;
}, []);
I have a query object that looks like this
{
"regions": [],
"countries": [],
"channels": [],
"partners": [],
"branches": [],
"agents": []
}
After populating the arrays in the object it looks like this.
{
"regions": [{
"key": "101",
"value": "Middle East(XX)"
}],
"countries": [],
"channels": [],
"partners": [{
"key": "201",
"value": "Partner A"
}, {
"key": "202",
"value": "Partner B"
}],
"branches": [{
"key": "401",
"value": "Bangalore"
}, {
"key": "402",
"value": "Chennai"
}],
"agents": [{
"key": "501",
"value": "IBM - Metlife"
}]
}
I'm trying to loop through each of these arrays and determine if I should show the filter component. If any of the arrays in the object holds value, I should be showing the filter component
The code:
case false:
let itemsInQuery = 0;
Object.keys(query).forEach((item) => {
itemsInQuery = query[item].length ? itemsInQuery++ : itemsInQuery;
})
itemsInQuery ? this.setState({showBubbles: true, query}) : this.setState({showBubbles: false, query})
break;
I'm not sure what is wrong here, but itemsInQuery is always zero. Also, is there a better way to do this?
Thank you in advance!
If any of the array have items in, you want a boolean to be true?
This sounds like a case for .some which on an array will take a predicate and return true if any item in that array matches the predicate.
const shouldShow = Object.keys(data).some(key => data[key].length > 0)
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/some
The problem is with this:
itemsInQuery = query[item].length ? itemsInQuery++
The ++ postfix operator returns the current value of itemsInQuery to the rest of the expression (i.e. 0) and then increments that variable to 1. But this is nullified by the assignment that happens afterwards to itemsInQuery which is the value 0.
So don't use ++ in an expression.
You can use this += instead:
itemsInQuery += query[item].length ? 1 : 0;
Does this do what you want?
var data1 = {
"regions": [{
"key": "101",
"value": "Middle East(XX)"
}],
"countries": [],
"channels": [],
"partners": [{
"key": "201",
"value": "Partner A"
}, {
"key": "202",
"value": "Partner B"
}],
"branches": [{
"key": "401",
"value": "Bangalore"
}, {
"key": "402",
"value": "Chennai"
}],
"agents": [{
"key": "501",
"value": "IBM - Metlife"
}]
};
var data2 = {
"regions": [],
"countries": [],
"channels": [],
"partners": [],
"branches": [],
"agents": []
}
function hasEntries (data) {
for (var index in data) {
if (Array.isArray(data[index]) && data[index].length) {
return true;
}
}
return false;
}
console.log(hasEntries(data1));
console.log(hasEntries(data2));