object map with the name - javascript

I have an object (obj), I need to map or loop through the dataToInsert object and display the result as shown in the data object. The complexity is that I need to display part of the name of the object in the field value (FOI_OMG_101 to 101)
const dataToInsert = {
FOI_OMG_101 : {
name : "jghj.pdf",
value: "base64"
}
}
const data=
{
field: "101",
fileName: "jghj.pdf",
value:"base64"
}
this is what I have now
for (const [key, value] of
Object.entries(dataToInsert.FOI_OMG_101)) {
console.log(`${key}: ${value}`);
}

const dataToInsert = {
FOI_OMG_101 : {
name : "jghj.pdf",
value: "base64"
}
};
const data = {
field: "101",
fileName: "jghj.pdf",
value:"base64"
};
// Look at the entries of the full object,
// so you do not have to know the FOI_OMG_101 field name beforehand.
for ([ field, file ] of Object.entries( dataToInsert )) {
console.log( field ); // FOI_OMG_101
console.log( JSON.stringify( file )); // {"name":"jghj.pdf","value":"base64"}
const output = {
field: field,
fileName: file.name,
value: file.value
};
console.log( JSON.stringify( output )); // {"field":"FOI_OMG_101","fileName":"jghj.pdf","value":"base64"}
}
You can add additional string manipulation if you have to parse the number 101 out of the string FOI_OMG_101.

You need to split the key on those objects in the loop, and take the value from the last index of this split key as:
export default function App() {
const dataToInsert = {
FOI_OMG_101: {
name: "jghj.pdf",
value: "base64"
},
FOI_OMG_102: {
name: "abc.pdf",
value: "base64"
}
};
const [arrData, setArrData] = useState([]);
useEffect(() => {
let newArr = [];
Object.keys(dataToInsert).map((keyName, index) => {
const fieldNameArr = keyName.split("_");
newArr = [
...newArr,
{
field: fieldNameArr.at(-1),
fileName: dataToInsert[keyName].name,
value: dataToInsert[keyName].value
}
];
});
setArrData(newArr);
}, []);
useEffect(() => {
console.log("arrData", arrData);
}, [arrData]);
return (
<div className="App">
{arrData.map((item, index) => {
return <li key={index}>{JSON.stringify(item)}</li>;
})}
</div>
);
}
This is just an example of splitting, you can handle it as you wish. Here, is the sandbox link.

Related

Trying to access the name of the object

I am trying to access the name of the object (FOI_OMG_101) and extract 101 from the name and display it in output.field
const dataToInsert = {
FOI_OMG_101 : {
name : "jghj.pdf",
value: "base64"
}
};
const output = {
field: dataToInsert.substring(8),
fileName: dataToInsert.FOI_OMG_101.name,
value: dataToInsert.FOI_OMG_101.value
}
You can create a function that accepts a source object and a key and returns the desired target object.
For extracting the number out of the key, you can split the key by _ and then grab the last item using at.
function generateOutput(source, key) {
const desiredKey = Object.keys(source).find((k) => k === key);
if (!desiredKey) {
return null;
}
return {
field: desiredKey.split("_").at(-1),
fileName: source[key].name,
value: source[key].value,
};
}
const
dataToInsert = { FOI_OMG_101: { name: "jghj.pdf", value: "base64" } },
key = "FOI_OMG_101";
console.log(generateOutput(dataToInsert, key));
you can do something like this
const dataToInsert = {
FOI_OMG_101: {
name: "jghj.pdf",
value: "base64"
}
};
const output = Object.entries(dataToInsert).reduce((res, [key, {name, value}]) => ({
field: key.split('_').pop(),
fileName: name,
value
}), {})
console.log(output)

How to convert an array of objects into a single object using reduce?

I have the following array of object.
[
{ claimNumber1: 'R12345', checkNumber1: '' },
{ claimNumber2: 'T1234', checkNumber2: 'abcd' },
{ claimNumber3: 'Z4567', checkNumber3: 'qwer' }
]
Using reduce, I want to convert this to below.
{
claimNumber1:'R12345',
checkNumber1:'',
claimNumber2:'T1234',
checkNumber2:'',
claimNumber3:'Z4567',
checkNumber3:'',
}
I tried below but didn't get what I expected.
.reduce((obj, item) =>{
return {...obj,item}
} ,{});
You should spread the item object, because item is an object
const arr = [
{ claimNumber1: "R12345", checkNumber1: "" },
{ claimNumber2: "T1234", checkNumber2: "abcd" },
{ claimNumber3: "Z4567", checkNumber3: "qwer" },
];
const result = arr.reduce((obj, item, i) => {
return { ...obj, ...item, [`checkNumber${i + 1}`]: "" };
}, {});
console.log(result);
Almost there. You just need to spread the item as well.
.reduce((obj, item) => {
return {
...obj,
...item,
};
}, {});
I think you should spread every item in reducer.
Here is my code.
const res = arr.reduce((prev, item) => {
return { ...prev, ...item };
}, {});
And result is
{
claimNumber1: 'R12345',
checkNumber1: '',
claimNumber2: 'T1234',
checkNumber2: 'abcd',
claimNumber3: 'Z4567',
checkNumber3: 'qwer'
}
I'm not sure of the benefit of using reduce in this situation. A simple loop would be self-documenting, and easier to read.
const data = [
{ claimNumber1: 'R12345', checkNumber1: '' },
{ claimNumber2: 'T1234', checkNumber2: 'abcd' },
{ claimNumber3: 'Z4567', checkNumber3: 'qwer' }
];
const out = {};
// For every object in the array
for (const obj of data) {
// Get an array of its keys and iterate over them
for (const key of Object.keys(obj)) {
// If it's a claim add that value to the output
// object property, otherwise set that property value
// to an empty string.
if (key.startsWith('claim')) {
out[key] = obj[key];
} else {
out[key] = '';
}
}
}
console.log(out);
Additional documentation
Object.keys

How to dynamically add data from an array with objects to a nested array?

I have this set of data that I get dynamically -
This is the data I dynamically get
and my question is how can I get the values from the key, pattern and label and put them in a nested object like this - how should the nested object look like.
My current code is
let mergeTagsObj = {};
const merg = function(arr){
const propertyDataMap = arr.map(x => x.key);
propertyDataMap.forEach(x => {
mergeTagsObj[x] = {}
});
console.log(mergeTagsObj);
// console.log(object);
};
merg(displayArr)
displayArr has the data that I dynamically get, and I map each one to get the key so I can then give the object property a name. But after that I need to get the other 2 (pattern and label) and put it in the mergeTagsObj;
ex: mergeTagsObj = {
firstName:{
name:{label}
value:{pattern}
},
...
};
You can add the pattern and label in your forEach and any other logic that you might need to transform the data.
const data = [{key: 'firstName', pattern: "{{firstName}}", label: "First Name"},
{key: 'lastName', pattern: "{{lastName}}", label: "Last Name"},
{key: 'unsubscribeLink', pattern: "{{unsubscribeLink}}", label: "Unsubscribe Link"}
]
const transformDataToTagsObject = (dData) => {
const dynamicData = {};
dData.forEach((currentData, index) => {
const currentKey = currentData.key
const name = currentData.label
let value = currentData.pattern
if(currentData.key === 'unsubscribeLink'){
value = `<a href='${value}'>Unsubscribe</a>`
}
dynamicData[currentKey] = {
name,
value
}
})
const tagsObject = {
tags: dynamicData
}
return tagsObject;
}
const finalResults = transformDataToTagsObject(data)
console.log(finalResults)
Not most elegant solution, but I think this should work. Don't need to create the array of keys first you can just iterate over the arr of objects.
const merg = function(arr){
arr.forEach(x => {
mergeTagsObj[x.key] = {};
mergeTagsObj[x.key]['name'] = x.label;
mergeTagsObj[x.key]['value'] = x.pattern
});
console.log(mergeTagsObj);
// console.log(object);
};
// Given
const data = [
{key: "firstName", pattern: "{{firstName}}", label: "First Name"},
{key: "unsubscribeLink", pattern: "{{unsubscribeLink}}", label: "Unsubscribe Link"}
];
const tagsObject = data.reduce((obj, item) => {
const key = item.key;
const name = item.label;
let value = item.pattern;
if (key === 'unsubscribeLink') value = 'Unsubscribe';
return {...obj, [key]: {name, value}};
}, {});
console.log(tagsObject);

Create an Dynamic Array Object with key value pairs

I need to create an Dynamic key value pairs from the existing object
const balanceScheule = 1255;
const reqCost = [{Labour Cost: "1555"}, {Material Cost: "1575"}]; // key is dynamic and keeps on changing
const amfqtyCost = 1416;
Here the logic is to create an new array of object and subtract the amfqtyCost from reqCost
Logic i Have written
reqCost.forEach(element => {
const adjustedAmount = Object.entries(element).map((m) => {
let adjustedAmount = parseInt(m[1]) - amfqtyCost;
return adjustedAmount;
});
// console.log(...adjustedAmount)
});
this return 139 and 159 which is (1555 - 1416 = 139) and (1575 1416 = 159) respectively
Expected output :
[{Labour Cost: "139"}, {Material Cost: "159"}]
How to do i merge ?
You just need to return the updated object from within map function. Also for the outer iteration use map instead of forEach to return the final result
const balanceScheule = 1255;
const reqCost = [{
'Labour Cost': "1555",
}, {
'Material Cost': "1575",
}]; // key is dynamic and keeps on changing
const amfqtyCost = 1416;
const updatedData = reqCost.map(element => {
return Object.assign({}, ...Object.entries(element).map(([key, value]) => {
let adjustedAmount = parseInt(value) - amfqtyCost;
return {
[key]: String(adjustedAmount)
};
}));
});
console.log(updatedData);
You can do something like this:
const reqCost = [{
'Labour Cost': "1555"
}, {
'Material Cost': "1575"
}];
const amfqtyCost = 1416;
const adjustedCost = reqCost.map(cost => ({
[Object.keys(cost)[0]]: (parseInt(Object.values(cost)[0]) - amfqtyCost).toFixed(0)
}));
console.log(adjustedCost);
// OR, if you prefer to be a bit more verbose:
const adjustedCost2 = reqCost.map(cost => {
const [key, value] = Object.entries(cost)[0];
return {
[key]: (parseInt(value) - amfqtyCost).toFixed(0)
}
});
console.log(adjustedCost2);
You can reverse the Object.entries
{ key : value } => [ [ key, value ] ]
transformation by using Object.fromEntries
[ [ key, value ] ] => { key : value }
the code will look like this
reqCost.map((obj) =>
Object.fromEntries(
Object.entries(obj).map(([key, value]) => [
key,
parseInt(value) - amfqtyCost,
])
)
);

Filtering logic for an array of object based on tabs

I have 3 tabs tabA, tabB, tabC and I have a common array of object which is being displayed in all these 3 tabs i.e
` data=[{value:"someValue (tabA) RO"},{value:"someValue (tabA) RW" },
{value:"someValue (tabB) RO"},{value:"someValue (tabB) RW" } ,
{value:"someValue (tabC) RO"},{value:"someValue (tabC) RW" }]`
filtering criteria is that when I am in tabA it should display both the tabA RO ,Rw values and only RO values of other tabs , same way if I am in tabB it should display both RO,RW values of tabB and only RO values of other tabs,same for the rest of the tabs . could somebody give me the logic.
Not sure what the data structure you are talking. I assume it looks like below.
const data = [
{ value: "tabAsomeValueRO (tabA) RO" },
{ value: "tabAsomeValueRW (tabA) RW" },
{ value: "tabBsomeValueRO (tabB) RO" },
{ value: "tabBsomeValueRW (tabB) RW" },
{ value: "tabCsomeValueRO (tabC) RO" },
{ value: "tabCsomeValueRW (tabC) RW" }
]
/**
* convert to the following object
{
tabA: {
RO: "tabAsomeValueRO",
RW: "tabAsomeValueRW",
},
tabB: {
RO: "tabBsomeValueRO",
RW: "tabBsomeValueRW",
},
tabC: {
RO: "tabCsomeValueRO",
RW: "tabCsomeValueRW",
}
}
*/
const regex = /([^ ]+) \(([^\)]+)\) ([^ ]+)/;
const newData = data.map(val => val.value).reduce((accum, val) => {
const arr = regex.exec(val);
const value = arr[1];
const tabName = arr[2];
const rValue = arr[3];
if (!accum[tabName]) {
accum[tabName] = {};
}
accum[tabName][rValue] = value;
return accum;
}, {});
function getValue(tab) {
return Object.keys(newData).reduce((accum, tmpTab) => {
const tmpTabValue = newData[tmpTab];
if (tmpTab === tab) {
accum.push(tmpTabValue.RO);
accum.push(tmpTabValue.RW);
}
else {
accum.push(tmpTabValue.RO);
}
return accum;
}, []);
}
console.log("tabA", getValue("tabA"));
console.log("tabB", getValue("tabB"));
console.log("tabC", getValue("tabC"));

Categories

Resources