How to replace the keys "names" in javascript - javascript

Below is the object
{
'File_12345.ZLM': {
MeterID_12345: {
BASIC_INFO: [Object]
}
}
}
{
'File_678910.ZLM': {
MeterID_678910: {
BASIC_INFO: [Object],
}
}
}
===============================================================================================
I want File_12345.ZLM and File_678910.ZLM replaced with key name as "FileName" and
MeterID_12345 and MeterID_678910 replaced with "MeterId"
So Expected Output would be as below
{
'FileName': {
MeterId: {
BASIC_INFO: [Object]
}
}
}
{
'FileName': {
MeterId: {
BASIC_INFO: [Object],
}
}
}

As #efkah pointed out, the RegEx solution here:
const files = [{'File_12345.ZLM':{MeterID_12345:{BASIC_INFO:[]}}},{'File_678910.ZLM':{MeterID_678910:{BASIC_INFO:[]}}}];
const renamed = JSON.stringify(files)
.replaceAll(/File_\d+\.ZLM/g, 'FileName')
.replaceAll(/MeterID_\d+/g, 'MeterId');
const result = JSON.parse(renamed);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0 }

The idea is to grab the keys of the objects, since there is only one. With that we get to know the key we want to replace. Do it for both keys and voilà!
I've added a second way to do it, to flatten the objects a bit to make them easier to use, and to also not loose the filename and meterid info.
const files = [{
'File_12345.ZLM': {
MeterID_12345: {
BASIC_INFO: []
}
}
},
{
'File_678910.ZLM': {
MeterID_678910: {
BASIC_INFO: [],
}
}
}];
console.log(files.map(f=>{
const filename = Object.keys(f)[0];
f.FileName = f[filename]; delete f[filename];
const MeterId = Object.keys(f.FileName)[0];
f.FileName.MeterId = f.FileName[MeterId]; delete f.FileName[MeterId];
return f;
}));
const files2 = [{
'File_12345.ZLM': {
MeterID_12345: {
BASIC_INFO: []
}
}
},
{
'File_678910.ZLM': {
MeterID_678910: {
BASIC_INFO: [],
}
}
}];
console.log(files2.map(f=>{
const filename = Object.keys(f)[0];
const MeterId = Object.keys(f[filename])[0];
return {FileName:filename,MeterId,BASIC_INFO:f[filename][MeterId].BASIC_INFO};
}));

const data = [{
'File_12345.ZLM':{
MeterID_12345: {
BASIC_INFO: []
}
}
},{ 'File_678910.ZLM': { MeterID_678910: { BASIC_INFO: [], } } }]
const obj = data.map(item => {
const Meterkeys = Object.keys(item)
const Meterkey = Meterkeys.find(k => k.includes('File'))
if (Meterkey) {
const Filekeys = Object.keys(item[Meterkey])
const Filekey = Filekeys.find(k => k.includes('Meter'))
const res = {
...item,
FileName: {
...item[Meterkey],
MeterId: (item[Meterkey])[Filekey]
}
}
delete res[Meterkey]
delete res.FileName[Filekey]
return res;
} else {
return item
}
})
console.log(obj)

const obj = {oldKey: 'value'};
obj['newKey'] = obj['oldKey'];
delete obj['oldKey'];
console.log(obj); // 👉️ {newKey: 'value'}

Related

Node.js - How to merge objects inside an array based on condition?

In Node.js, I have 3 sets of data like
[
{
"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
"dailyData":159392.235451,
"dailyDataInUSC":255.284807
}
]
and
[
{
"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
"monthlyData":159392.235451,
"monthlyDataInUSC":255.284807
},
{
"userId":"23fs6fds3-34k4-17de-3123-d2ec81e8aaf3",
"monthlyData":349392.455451,
"monthlyDataInUSC":655.234807
}
]
and
[
{
"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
"threeMonthsData":159392.235451,
"threeMonthsDataInUSC":255.284807
},
{
"userId":"23fs6fds3-34k4-17de-3123-d2ec81e8aaf3",
"threeMonthsData":349392.455451,
"threeMonthsDataInUSC":655.234807
},
{
"userId":"34sdf34-67j4-54nd-6763-d2ec81e8aaf3",
"threeMonthsData":6789392.455451,
"threeMonthsDataInUSC":905.655807
}
]
How can I combine this to one object based on userId(filter) inside an array.
Eg, output should be like
[
{
"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
"dailyData":159392.235451,
"dailyDataInUSC":255.284807,
"monthlyData":159392.235451,
"monthlyDataInUSC":255.284807,
"threeMonthsData":159392.235451,
"threeMonthsDataInUSC":255.284807
}
]
Please help me to achieve this.
A combination of spread, reduce and findIndex can be used to solve the problem.
Combine the original arrays into a single array using the spread operator.
Use reduce to group the elements by key (in this case userId)
Something like this :
const dailyData = [{"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3","dailyData":159392.235451,"dailyDataInUSC":255.284807}];
const monthlyData = [{"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3","monthlyData":159392.235451,"monthlyDataInUSC":255.284807}, {"userId":"23fs6fds3-34k4-17de-3123-d2ec81e8aaf3","monthlyData":349392.455451,"monthlyDataInUSC":655.234807}]
const triMonthlyData = [{"userId":"54c7f3ef-64d4-40de-8100-d2ec81e8aaf3","threeMonthsData":159392.235451,"threeMonthsDataInUSC":255.284807}, {"userId":"23fs6fds3-34k4-17de-3123-d2ec81e8aaf3","threeMonthsData":349392.455451,"threeMonthsDataInUSC":655.234807}, {"userId":"34sdf34-67j4-54nd-6763-d2ec81e8aaf3","threeMonthsData":6789392.455451,"threeMonthsDataInUSC":905.655807}]
const combinedData = [...dailyData, ...monthlyData, ...triMonthlyData].reduce((mergedResult, curElement) => {
let matchingElementIdx = mergedResult.findIndex(ele => ele.userId === curElement.userId);
if (matchingElementIdx !== -1) {
mergedResult[matchingElementIdx] = {...mergedResult[matchingElementIdx], ...curElement};
} else {
mergedResult = [...mergedResult, curElement];
}
return mergedResult;
}, []);
console.log(combinedData);
const aa = () => {
let aa = [
{
userId: "54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
dailyData: 159392.235451,
dailyDataInUSC: 255.284807
}
];
let bb = [
{
userId: "54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
monthlyData: 159392.235451,
monthlyDataInUSC: 255.284807
},
{
userId: "23fs6fds3-34k4-17de-3123-d2ec81e8aaf3",
monthlyData: 349392.455451,
monthlyDataInUSC: 655.234807
}
];
let cc = [
{
userId: "54c7f3ef-64d4-40de-8100-d2ec81e8aaf3",
threeMonthsData: 159392.235451,
threeMonthsDataInUSC: 255.284807
},
{
userId: "23fs6fds3-34k4-17de-3123-d2ec81e8aaf3",
threeMonthsData: 349392.455451,
threeMonthsDataInUSC: 655.234807
},
{
userId: "34sdf34-67j4-54nd-6763-d2ec81e8aaf3",
threeMonthsData: 6789392.455451,
threeMonthsDataInUSC: 905.655807
}
];
let newArrObj = aa;
bb.forEach(item => {
let index = newArrObj.findIndex(item1 => item1.userId === item.userId);
if (index === -1) {
newArrObj = [...newArrObj, item];
} else {
newArrObj[index] = { ...newArrObj[index], ...item };
}
});
cc.forEach(item => {
let index = newArrObj.findIndex(item1 => item1.userId === item.userId);
if (index === -1) {
newArrObj = [...newArrObj, item];
} else {
newArrObj[index] = { ...newArrObj[index], ...item };
}
});
console.log(newArrObj);
};

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"));

Put object in nested object

Ik have to object and I want to combine those together the right way. I use this code to get them together:
return { record, voorraad: resultsr.filter(x => x != null) }
the output of this will be
{
record:{
_id:"5e8c226e62e43e41b59fe3d3",
naam:"Dames fietsen"
},
voorraad:[
{
_id:"5e8cc9e059fcf75489ebac84",
categorie:"5e8c226e62e43e41b59fe3d3",
status:1
}
]
}
But I like to have it this way
{
record:{
_id:"5e8c226e62e43e41b59fe3d3",
naam:"Dames fietsen",
voorraad:[
{
_id:"5e8cc9e059fcf75489ebac84",
categorie:"5e8c226e62e43e41b59fe3d3",
status:1
}
]
}
}
Who can help me?
this way ?
var data = {
"record":{
"_id":"5e8c226e62e43e41b59fe3d3",
"naam":"Dames fietsen"
},
"voorraad":[
{
"_id":"5e8cc9e059fcf75489ebac84",
"categorie":"5e8c226e62e43e41b59fe3d3",
"status":1
}
]
}
data.record.voorraad = data.voorraad
delete data.voorraad
console.log( JSON.stringify( data, 0 ,2))
uses destructuring:
const data = {
record:{
_id:"5e8c226e62e43e41b59fe3d3",
naam:"Dames fietsen"
},
voorraad:[
{
_id:"5e8cc9e059fcf75489ebac84",
categorie:"5e8c226e62e43e41b59fe3d3",
status:1
}
]
};
const { record, voorraad } = data;
const test = { ...record, voorraad: voorraad.filter(x => x != null) }
console.log(test);
// you have these
const record = {"_id":"5e8c226e62e43e41b59fe3d3", "naam":"Dames fietsen"};
const results = [
{
"_id":"5e8cc9e059fcf75489ebac84",
"categorie":"5e8c226e62e43e41b59fe3d3",
"status":1
}
];
// so just do this
record.voorraad = results.filter(x => x);
const returnValue = { record };
// and returnValue is what you want
console.log(returnValue);

How to fix my recursive function? I am receiving either an array of an array of data

I am trying to create a recursive function that will go through an object similar to a directory with subdirectories, and output the'file' objects in an array. However, it seems that i am getting an array of arrays rather than a simple array with the objects I am expecting to see...
The bottom of the code has some console.logs that return:
console.log(findEntry(repAll, '/first')); // ===> [ { name: '/first' }, [] ]
console.log(findEntry(repAll, '/second')); // ===> [ [ { name: '/second' }, { name: '/second' } ] ]
const repAll = {
file1: {
name: "/first"
},
SubDir: {
file2: {
name: "/second"
},
file3: {
name: "/second"
}
}
};
const req = {};
function findEntry(data, name) {
let x = [];
for (const value of Object.values(data)) {
// Is this a leaf node or a container?
if (value.name) {
// Leaf, return it if it's a match
if (value.name === name) {
x.push(value);
}
} else {
// Container, look inside it recursively
const entry = findEntry(value, name);
x.push(entry);
}
}
return x;
}
console.log('search: /first');
console.log(findEntry(repAll, '/first'));
console.log('search: /second');
console.log(findEntry(repAll, '/second'));
You could spread the result of findEntry instead of simply pushing the array.
const repAll = {
file1: {
name: "/first"
},
SubDir: {
file2: {
name: "/second"
},
file3: {
name: "/second"
}
}
};
const req = {};
function findEntry(data, name) {
let x = [];
for (const value of Object.values(data)) {
// Is this a leaf node or a container?
if (value.name) {
// Leaf, return it if it's a match
if (value.name === name) {
x.push(value);
}
} else {
// Container, look inside it recursively
x.push(...findEntry(value, name));
}
}
return x;
}
console.log('search: /first');
console.log(findEntry(repAll, '/first'));
console.log('search: /second');
console.log(findEntry(repAll, '/second'));
With your approach :
function findEntry(data, name,x) {
for (const value of Object.values(data)) {
// Is this a leaf node or a container?
if (value.name) {
// Leaf, return it if it's a match
if (value.name === name) {
x.push(value);
}
} else {
// Container, look inside it recursively
const entry = findEntry(value, name,x);
x.push(entry);
}
}
return x;
}
Now call it like this :
let arr=[];
console.log(findEntry(repAll, '/first',arr));

Better way to map a deep object to new object

This code works for converting the JSON to an object where each name object turns into the key for either its value, or if it instead has its own element object breaks that out and does the same to its contents.
Is there a better way to do this that would also allow for more extensiblity of the JSON schema?
Is there a way I can get it all down to a simpler function that I can pass the first element and have it convert it down to whatever depth the schema goes?
const fs = require('fs');
{
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version='1.0'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let depth = 0;
var compiled = {
[scheme.ele.name]: scheme.ele.ele.map(function(i) {
if (typeof i.ele != 'undefined') {
return {
[i.name]: i.ele.map(function(k) {
if (typeof k.ele != 'undefined') {
return {
[k.name]: k.ele.map(function(p) {
if (typeof p.ele != 'undefined') {
return {
[p.name]: p.ele
};
} else {
return {
[p.name]: p.value
};
}
})
};
} else {
return {
[k.name]: k.value
};
}
})
};
} else {
return {
[i.name]: i.value
};
}
})
};
}
console.log(JSON.stringify(compiled, 0, 2));
I should add, this is intended to eventually also apply validation and grab real data when it gets to the string objects.
The output looks like this:
{
"REPORT": [
{
"SEGMENT0": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
},
{
"SEGMENT1": [
{
"RECORD1": [
{
"NUMBER1": ""
},
{
"NUMBER2": ""
}
]
}
]
},
{
"SEGMENT2": []
},
{
"SEGMENT3": []
},
{
"SEGMENT4": []
},
{
"SEGMENT5": []
}
]
}
You could destructure the object, get name, ele and value and return a new object with name as key and either an array by mapping the objects of ele or the value.
const
getData = ({ name, ele, value }) => ({
[name]: Array.isArray(ele)
? ele.map(getData)
: value
});
var scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0\'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root,
result = getData(scheme.ele);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina's answer is cleaner but this looks a bit more like your code so I figured I'd post it anyway.
let scheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":""},{"name":"NUMBER2","value":"1"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"2"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
let newScheme = JSON.parse('{"$schema":{"root":{"name":"THINGY","dtd":{"name":"DOCTYPE","value":"something.dtd","commentBefore":["?xml version=\'1.0 \'?","Version NULL"]},"ele":{"name":"REPORT","ele":[{"name":"SEGMENT0","ele":[{"name":"NUMBER1","value":"1"},{"name":"NUMBER2","value":"3"}]},{"name":"SEGMENT1","ele":[{"name":"RECORD1","ele":[{"name":"NUMBER1","value":"4"},{"name":"NUMBER2","value":""}]}]},{"name":"SEGMENT2","ele":[]},{"name":"SEGMENT3","ele":[]},{"name":"SEGMENT4","ele":[]},{"name":"SEGMENT5","ele":[]}]}}}}').$schema.root;
//Yay, recursion!
function mapObj(a, o = {}) {
let array = o[a.name] || [];
for (let i = 0; i < a.ele.length; i++) {
let b = a.ele[i];
array[i] = b.ele ?
mapObj(b, array[i]) : {
[b.name]: b.value
};
}
o[a.name] = array;
return o;
}
let obj = mapObj(scheme.ele);
console.log(obj);
console.log(mapObj(newScheme.ele, obj));

Categories

Resources