How to store object values by getting the key dynamically? - javascript

Using the following array of objects, how do I just get the values for each of the key and save it into the desired name and value structure format mentioned below?
{
list: [
[
{
Desc: {
value: '7777 - Florida Hurricane'
},
DSTR_NR: {
value: '7777'
}
},
{
ST_NM: {
value: 'Alaska'
},
ST_CD: {
value: 'AK'
}
},
{
Desc: {
value: '7172 - Virginia Severe Storm(s)'
},
DSTR_NR: {
value: '7172'
}
},
{
ST_NM: {
value: 'Florida'
},
ST_CD: {
value: 'FL'
}
},
{
Desc: {
value: '7002 - Maryland Hurricane'
},
DSTR_NR: {
value: '7002'
}
},
{
ST_NM: {
value: 'Louisiana'
},
ST_CD: {
value: 'LA'
}
}
]
]
}
Desired format that I need regardless if the api returns disaster related data or states related data. I just need to store the data values in name/value pair like the following:
{
list: [
{
name: '7777',
value: '7777 - Florida Hurricane'
},
{
name: 'AK',
value: 'Alaska'
},
...
]
}
Here's my current code:
let newData = {}
list.forEach((value) => {
Object.keys(value).forEach((key) => {
if(newData[key] === undefined){
newData[key] = [value[key]]
} else {
newData[key].push(value[key])
}
})
});

You can map through the object like so
const res = {
list: [
[
{
Desc: {
value: '7777 - Florida Hurricane'
},
DSTR_NR: {
value: '7777'
}
},
{
ST_NM: {
value: 'Alaska'
},
ST_CD: {
value: 'AK'
}
},
{
Desc: {
value: '7172 - Virginia Severe Storm(s)'
},
DSTR_NR: {
value: '7172'
}
},
{
ST_NM: {
value: 'Florida'
},
ST_CD: {
value: 'FL'
}
},
{
Desc: {
value: '7002 - Maryland Hurricane'
},
DSTR_NR: {
value: '7002'
}
},
{
ST_NM: {
value: 'Louisiana'
},
ST_CD: {
value: 'LA'
}
}
]
]
}
const list = res.list[0];
const format = list.map(i => {
const items = Object.values(i);
const newItem = {}
newItem.name = items[1].value;
newItem.value = items[0].value;
return newItem
})
console.log(format)

If the data contains always the value first and the name second, you can do this:
// let response = { list: [...] }
let result = {
list: []
};
response.list.forEach(sublist => {
sublist.forEach(elem => {
let keys = Object.keys(elem);
result.list.push({
name: elem[ keys[1] ].value,
value: elem[ keys[0] ].value,
})
});
})
console.log("RESULT: ", result);

Related

combine array of object if atleast one property is common

//this one is actual array
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
>
//and this is the array that I want
let outPut =
[
{
name:'shanu',
label:['ak','pk'],
value:[1,2]
},
{
name:'bhanu',
label:['tk'],
value:[3]
}
]
You can use Array.prototype.reduce() like this:
const data = [
{
name: 'shanu',
label: 'ak',
value: 1,
},
{
name: 'shanu',
label: 'pk',
value: 2,
},
{
name: 'bhanu',
label: 'tk',
value: 3,
},
];
const output = data.reduce((prev, curr) => {
const tmp = prev.find((e) => e.name === curr.name)
if (tmp) {
tmp.label.push(curr.label)
tmp.value.push(curr.value)
} else {
prev.push({
name: curr.name,
label: [curr.label],
value: [curr.value],
})
}
return prev
}, [])
console.log(output)

How to reformat payload response from the backend to the desired format?

How can I change the structure of the payload on the frontend that's coming from the api. Here is the current data structure:
{
listById: [
[
{
Desc: {
value: '7777 - Florida Hurricane'
},
DSTR_NR: {
value: '7777'
}
},
{
Desc: {
value: '7172 - Virginia Severe Storm(s)'
},
DSTR_NR: {
value: '7172'
}
}
]
]
}
How can I convert it into the following desired structure?
{
list: [
{
name: '7777',
value: '7777 - Florida Hurricane'
},
{
name: '7172',
value: '7172 - Virginia Severe Storm(s)'
}
]
}
This is what my code looks like:
formatData = action => {
const id = action.meta;
let obj = {...state.listById};
obj[id] = action.payload;
let x = {
...state,
listById: Object.values(obj)
};
return x;
}
listById is an array with another array inside?? Have you tried to use Array.prototype.map() ?
// your list
let listById = [
[
{
Desc: {
value: '7777 - Florida Hurricane'
},
DSTR_NR: {
value: '7777'
}
},
{
Desc: {
value: '7172 - Virginia Severe Storm(s)'
},
DSTR_NR: {
value: '7172'
}
}
]
]
// merge/flatten the arrays and mapping them to the final list
newList = [].concat.apply([],listById).map(o => {
return {
name: o["DSTR_NR"].value,
value: o["Desc"].value
}
})
alert(JSON.stringify(newList))
Hope it can help a bit.
const response = {
listById: [
[
{
Desc: {
value: '7777 - Florida Hurricane'
},
DSTR_NR: {
value: '7777'
}
},
{
Desc: {
value: '7172 - Virginia Severe Storm(s)'
},
DSTR_NR: {
value: '7172'
}
}
]
]
}
const list
= response.listById ?
response.listById[0]?.map(
({Desc: {value}, DSTR_NR: {value: name}}) => ({
name,
value
}))
: []
const result = {list: list || []}
console.log(result)

Extract parameters from object

I have next object:
const types = {
sometypes: {
TYPE1: { name: 'type1', value: '1' },
TYPE2: { name: 'type2', value: '2' },
TYPE3: { name: 'type3', value: '3' },
},
TYPE4: { name: 'type4' },
};
how can I extract all name fields?
Expected result: ['type1','type2','type3','type4']
You can create a recursive function to loop through the object.
const types = {
sometypes: {
TYPE1: {
name: 'type1',
value: '1'
},
TYPE2: {
name: 'type2',
value: '2'
},
TYPE3: {
name: 'type3',
value: '3'
},
},
TYPE4: {
name: 'type4'
},
};
function extractNames(obj) {
let result = [];
Object.keys(obj).forEach(k => {
if (k == 'name') {
result.push(obj[k]);
} else if (typeof obj[k] == 'object') {
result.push(...extractNames(obj[k]));
}
});
return result;
}
console.log(extractNames(types));
Take entries of object and then map it accordingly.(I'm assuming your object is not nested)
var types = { sometypes: { TYPE1: { name: 'type1', value: '1' }, TYPE2: { name: 'type2', value: '2' }, TYPE3: { name: 'type3', value: '3' }, }, TYPE4: { name: 'type4' },};
var result = Object.entries(types).flatMap(([k,v])=> v.name ? v.name : Object.values(v).map(({name})=>name));
console.log(result);
This getNames function does it recursively.
const types = getSourceObject();
function getNames(obj, names){
const keys = Object.keys(obj);
keys.forEach( (key) => {
if(obj[key].name){ names.push(obj[key].name); }
else{ getNames(obj[key], names); }
});
}
const namesArr = [];
getNames(types, namesArr);
console.log(namesArr);
function getSourceObject(){
return {
sometypes: {
TYPE1: { name: 'type1', value: '1' },
TYPE2: { name: 'type2', value: '2' },
TYPE3: { name: 'type3', value: '3' }
},
TYPE4: { name: 'type4' }
};
}

How to filtering between array of sub arrays and array of sub arrays in javascript?

I have got two arrays of objects. I want to filter data based on PermissionObj.
This is coming from database. Here are arrays of sub-arrays in the permissionObj.
const PermissionObj = {
permission: [
{
books: [
{
label: "Can View",
value: "can_view"
}
]
},
{
Journals: [
{
label: "Can View",
value: "can_view"
},
{
label: "Can Create",
value: "can_create"
}
]
},
{
deal: [
{
label: "Can update",
value: "can_update"
},
{
label: "Can delete",
value: "can_delete"
}
]
}
]
}
this is static data. I want to compare this data based on PermissionObj.
const data = [
{
label: "books",
value: "can_view"
},
{
label: "deal",
content: [
{
value: "can_update"
},
{
value: "can_delete"
},
{ value: "can_view" }
]
},
{
label: "Articles"
},
{
label: "Journals",
content: [
{
value: "can_create"
},
{
value: "can_view"
},
{
value: "can_delete"
},
{
value: "can_edit"
}
]
}
]
I am trying to filter the data array of the object based on PermissionObj array of objects. here is my trying code.
const permKeys = PermissionObj.permission.flatMap(item => Object.keys(item));
const filteredData = data.filter(({ label }) => permKeys.includes(label));
console.log(filteredData);
Here is my problem, I have been faced is that I don't want to get can_edit, can_delete if it doesn't match with permission objects in journals. In my permission objects, There is no can_edit and can_delete in journals.
My accepted Output would be this format :
const data = [
{
label: "books",
value: "can_view"
},
{
label: "deal",
content: [
{
value: "can_update"
},
{
value: "can_delete"
}
]
},
{
label: "Journals",
content: [
{
value: "can_create"
},
{
value: "can_view"
}
]
}
]
It is possible to use reduce method and apply logic to decide what data should be pushed:
const result = data.reduce((a, c) => {
let filterObj = PermissionObj.permission.find(f => f[c.label]);
if (filterObj) {
if (c.value) {
a.push(c);
}
if (c.content) {
c.content = c.content.filter(f => filterObj[c.label]
.some(s => s.value.toLowerCase() == f.value.toLowerCase()));
a.push(c);
}
}
return a;
},[])
An example:
const PermissionObj = {
permission: [
{
"books": [
{
"label": "Can View",
"value": "can_view"
}
]
},
{
"Journals": [
{
"label": "Can View",
"value": "can_view"
},
{
"label": "Can Create",
"value": "can_create"
}
]
},
{
"deal": [
{
"label": "Can update",
"value": "can_update"
},
{
"label": "Can delete",
"value": "can_delete"
}
]
}
]
};
const data = [
{
label: "books",
value: "can_view"
},
{
label: "deal",
content: [
{
value: "can_update"
},
{
value: "can_delete"
},
{
value:"can_view"
}
]
},
{
label: "Articles",
},
{
label: "Journals",
content: [
{
value: "can_create"
},
{
value: "can_view"
},
{
value: "can_delete"
},
{
value: "can_edit"
}
]
}
];
const result = data.reduce((a, c) => {
let filterObj = PermissionObj.permission.find(f => f[c.label]);
if (filterObj) {
if (c.value) {
a.push(c);
}
if (c.content) {
c.content = c.content.filter(f => filterObj[c.label].some(s => s.value.toLowerCase() == f.value.toLowerCase()));
a.push(c);
}
}
return a;
},[])
console.log(result);

Setting array keys dynamically based on length

Given an array in this format:
[
[{
name: "name",
value: "My-name"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test.com"
},
{
name: "comment",
value: "my-comment"
}
],
[{
name: "name",
value: "My-name2"
},
{
name: "qty",
value: "3"
},
{
name: "url",
value: "test2.com"
}
],
[{
name: "name",
value: "My-name3"
},
{
name: "qty",
value: "1"
},
{
name: "url",
value: "test3.com"
},
{
name: "comment",
value: "my-comment3"
}
]
]
I'm looking to switch that to:
[
[
{ name: "My-name" },
{ qty: "1" },
{ url: "test.com" },
{ comment: "my-comment", }
],[
{ name: "My-name2" },
{ qty: "3" },
{ url: "test2.com",
],[
{ name: "My-name3", },
{ qty: "1", },
{ url: "test3.com", },
{ comment: "my-comment3", }
]
]
In other words, swapping out the array keys but maintaining the object structure within each array element.
I've tried looping over each element and can swap the keys out using something like:
newArray[iCount][item.name] = item.value;
However I'm then struggling to preserve the object order. Note that the comment field may or may not appear in the object.
With Array.map() function:
var arr = [
[{name:"name",value:"My-name"},{name:"qty",value:"1"},{name:"url",value:"test.com"},{name:"comment",value:"my-comment"}],
[{name:"name",value:"My-name2"},{name:"qty",value:"3"},{name:"url",value:"test2.com"}],
[{name:"name",value:"My-name3"},{name:"qty",value:"1"},{name:"url",value:"test3.com"},{name:"comment",value:"my-comment3"}]
],
result = arr.map(function(a){
return a.map(function(obj){
var o = {};
o[obj.name] = obj.value
return o;
});
});
console.log(result);
Check my moreBetterOutput value. I think will be better.
If you still need a result like your example in the question then you can check output value.
const input = [
[
{
name:"name",
value:"My-name"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test.com"
},
{
name:"comment",
value:"my-comment"
}
],
[
{
name:"name",
value:"My-name2"
},
{
name:"qty",
value:"3"
},
{
name:"url",
value:"test2.com"
}
],
[
{
name:"name",
value:"My-name3"
},
{
name:"qty",
value:"1"
},
{
name:"url",
value:"test3.com"
},
{
name:"comment",
value:"my-comment3"
}
]
]
const output = input.map(arr => arr.map(obj => ({[obj.name]: obj.value})))
const moreBetterOutput = output.map(arr => arr.reduce((acc, item, index) => {
acc[Object.keys(item)[0]] = item[Object.keys(item)[0]];
return acc;
}, {}) )
//console.log(output);
console.log(moreBetterOutput);
Another map function:
const result = array.map( subarray =>
Object.assign(...subarray.map( ({name, value}) => ({ [name] : value }) ))
);

Categories

Resources