I have the following structure of info, that I need to convert into a JSON with properties and data. Originally its plain text, but I have converted it into an array to make it easier
[ '# Server',
'redis_version:5.0.5',
'redis_git_sha1:00000000',
'redis_git_dirty:0',
'redis_build_id:7983a619928f1f2d',
'redis_mode:standalone',
'os:Linux 3.10.0-693.5.2.el7.x86_64 x86_64',
'arch_bits:64',
'multiplexing_api:epoll',
'atomicvar_api:atomic-builtin',
'gcc_version:6.3.0',
'process_id:1',
'run_id:1348856f2bcc8af5cfef205f1880fedb68602201',
'tcp_port:6379',
'uptime_in_seconds:10484766',
'uptime_in_days:121',
'hz:10',
'configured_hz:10',
'lru_clock:11364638',
'executable:/data/redis-server',
'config_file:/etc/redis.conf',
'',
'# Clients',
'connected_clients:34',
'client_recent_max_input_buffer:2',
'client_recent_max_output_buffer:0',
'blocked_clients:0',
'',
'# Memory',
'used_memory:1568376',
'used_memory_human:1.50M',
'used_memory_rss:2768896',
'used_memory_rss_human:2.64M',
'used_memory_peak:5866848',
'used_memory_peak_human:5.60M',
'used_memory_peak_perc:26.73%',
'used_memory_overhead:1406080',
'used_memory_startup:791240',
'used_memory_dataset:162296',
'used_memory_dataset_perc:20.88%',
'allocator_allocated:1571256',
'allocator_active:2084864',
'allocator_resident:5722112',
'total_system_memory:33730531328',
'total_system_memory_human:31.41G',
'used_memory_lua:37888',
'used_memory_lua_human:37.00K' ]
And im trying to parse it into something that looks like the below structure
{
Server : {
redis_version : "5.0.5",
redis_git_sha1: "00000000"
...
},
Clients: {
connected_clientes: 54,
client_recent_max_input_buffer: 2,
...
}
Memory: {
used_memory: 1568376,
used_memory_human: "1.50M"
...
}
}
So far I have been able to create the subobjects
{ Server: {},
Clients: {},
Memory: {},
Persistence: {},
Stats: {},
Replication: {},
CPU: {},
Cluster: {},
Keyspace: {} }
Using this code where i managed to create the objects:
var obj = {};
console.log(lines)
for (let i in lines) {
if (lines[i].includes("#")) {
let prop = lines[i].toString()
let propFormat = prop.substring(2)
obj[propFormat] = {}
} else if (!lines[i].includes("#") && lines[i] != "") {
// console.log(lines[i])
}
}
But im stuck after that, can someone bring some light on how to continue?
I would use a forEach to loop through the array.
Then using .substring to check if it's a new 'key'; remember that key so you can add all the values, until the next key is found;
const data = [ '# Server', 'redis_version:5.0.5', 'redis_git_sha1:00000000', 'redis_git_dirty:0', 'redis_build_id:7983a619928f1f2d', 'redis_mode:standalone', 'os:Linux 3.10.0-693.5.2.el7.x86_64 x86_64', 'arch_bits:64', 'multiplexing_api:epoll', 'atomicvar_api:atomic-builtin', 'gcc_version:6.3.0', 'process_id:1', 'run_id:1348856f2bcc8af5cfef205f1880fedb68602201', 'tcp_port:6379', 'uptime_in_seconds:10484766', 'uptime_in_days:121', 'hz:10', 'configured_hz:10', 'lru_clock:11364638', 'executable:/data/redis-server', 'config_file:/etc/redis.conf', '', '# Clients', 'connected_clients:34', 'client_recent_max_input_buffer:2', 'client_recent_max_output_buffer:0', 'blocked_clients:0', '', '# Memory', 'used_memory:1568376', 'used_memory_human:1.50M', 'used_memory_rss:2768896', 'used_memory_rss_human:2.64M', 'used_memory_peak:5866848', 'used_memory_peak_human:5.60M', 'used_memory_peak_perc:26.73%', 'used_memory_overhead:1406080', 'used_memory_startup:791240', 'used_memory_dataset:162296', 'used_memory_dataset_perc:20.88%', 'allocator_allocated:1571256', 'allocator_active:2084864', 'allocator_resident:5722112', 'total_system_memory:33730531328', 'total_system_memory_human:31.41G', 'used_memory_lua:37888', 'used_memory_lua_human:37.00K' ];
// Result
let res = {};
// Remember latest prop
let latestProp = null;
// For each data entry
data.forEach((d) => {
// Starting with #: new key
const firstChar = d.substring(0, 1);
if (firstChar === '#') {
latestProp = d.substring(2);
res[latestProp] = {};
} else {
// Add key-value
let s = d.split(':');
if (s.length > 1) {
res[latestProp][s[0]] = s[1];
}
}
});
console.log(res);
My suggestion would be something like this:
//Declaring prop before the loop so that it isn't reset each iteration
let prop;
for(...) {
...
} else if (!lines[i].includes("#") && lines[i] != "") {
let split = lines[i].split(":");
let key = split[0];
let value = split[1];
obj[prop][key] = value
}
here is a working snippet using array.reduce , I also removed the "" values from the array
const tobeConverted= [ '# Server',
'redis_version:5.0.5',
'redis_git_sha1:00000000',
'redis_git_dirty:0',
'redis_build_id:7983a619928f1f2d',
'redis_mode:standalone',
'os:Linux 3.10.0-693.5.2.el7.x86_64 x86_64',
'arch_bits:64',
'multiplexing_api:epoll',
'atomicvar_api:atomic-builtin',
'gcc_version:6.3.0',
'process_id:1',
'run_id:1348856f2bcc8af5cfef205f1880fedb68602201',
'tcp_port:6379',
'uptime_in_seconds:10484766',
'uptime_in_days:121',
'hz:10',
'configured_hz:10',
'lru_clock:11364638',
'executable:/data/redis-server',
'config_file:/etc/redis.conf',
'# Clients',
'connected_clients:34',
'client_recent_max_input_buffer:2',
'client_recent_max_output_buffer:0',
'blocked_clients:0',
'# Memory',
'used_memory:1568376',
'used_memory_human:1.50M',
'used_memory_rss:2768896',
'used_memory_rss_human:2.64M',
'used_memory_peak:5866848',
'used_memory_peak_human:5.60M',
'used_memory_peak_perc:26.73%',
'used_memory_overhead:1406080',
'used_memory_startup:791240',
'used_memory_dataset:162296',
'used_memory_dataset_perc:20.88%',
'allocator_allocated:1571256',
'allocator_active:2084864',
'allocator_resident:5722112',
'total_system_memory:33730531328',
'total_system_memory_human:31.41G',
'used_memory_lua:37888',
'used_memory_lua_human:37.00K' ]
let index = 0;
let keys=[]
const reducedObj=tobeConverted.reduce((a,c)=>{
if(c.includes("#")){
const key= c.split("#")[1].trim()
keys.push(key)
index++;
return {...a,[key]:{}}
}else{
const split =c.split(":")
console.log(split)
const subkey =split[0].trim()
const subValue =split[1].trim()
a[keys[index-1]][subkey] = subValue;
}
return a
},{})
I think you can do something like this:
function parse (lines) {
const result = {};
let section;
lines.forEach((line) => {
if (line) {
if (line.startsWith('# ')) {
section = line.substring(2);
result[section] = {};
} else {
const [prop, value] = line.split(':');
result[section][prop] = value;
}
}
});
return result;
}
const textdata = [ '# Server', 'redis_version:5.0.5', 'redis_git_sha1:00000000', 'redis_git_dirty:0', 'redis_build_id:7983a619928f1f2d', 'redis_mode:standalone', 'os:Linux 3.10.0-693.5.2.el7.x86_64 x86_64', 'arch_bits:64', 'multiplexing_api:epoll', 'atomicvar_api:atomic-builtin', 'gcc_version:6.3.0', 'process_id:1', 'run_id:1348856f2bcc8af5cfef205f1880fedb68602201', 'tcp_port:6379', 'uptime_in_seconds:10484766', 'uptime_in_days:121', 'hz:10', 'configured_hz:10', 'lru_clock:11364638', 'executable:/data/redis-server', 'config_file:/etc/redis.conf', '', '# Clients', 'connected_clients:34', 'client_recent_max_input_buffer:2', 'client_recent_max_output_buffer:0', 'blocked_clients:0', '', '# Memory', 'used_memory:1568376', 'used_memory_human:1.50M', 'used_memory_rss:2768896', 'used_memory_rss_human:2.64M', 'used_memory_peak:5866848', 'used_memory_peak_human:5.60M', 'used_memory_peak_perc:26.73%', 'used_memory_overhead:1406080', 'used_memory_startup:791240', 'used_memory_dataset:162296', 'used_memory_dataset_perc:20.88%', 'allocator_allocated:1571256', 'allocator_active:2084864', 'allocator_resident:5722112', 'total_system_memory:33730531328', 'total_system_memory_human:31.41G', 'used_memory_lua:37888', 'used_memory_lua_human:37.00K' ];
const parsedObj = {};
for (data of textdata) {
// checking for keys
if (data.startsWith("#")) {
parsedObj[data.split(" ")[1]] = {};
continue;
}
if (Object.keys(parsedObj).length && data) {
let lastKeyFound = Object.keys(parsedObj).pop();
const [key, value] = data.split(':');
parsedObj[lastKeyFound][key] = value
}
}
// console.log(parsedObj)
// converting parsedObj to json
const textdataJson = JSON.stringify(parsedObj, null, 2)
console.log(textdataJson)
Related
I am trying to parse a TLV string and need to generate a nested object from that string.
const text = 'AA06ClaireCC04JackBB03TomEE05James'
The output needs to look like this:
"Acrobatic Artist": {
"AA": {
"Claire": {
"Curious Camper": {
"CC": {
"Jack": {
"Baddest Banana": {
"BB": {
"Tom": {
"Energetic Elephant": {
"EE": {
"James" : "LASTRECORD"
}
}
}
}
}
}
}
}
}
}
}
Here is what I currently have:
const map = {
AA: 'Acrobatic Artist',
BB: 'Baddest Banana',
CC: 'Curious Camper',
DD: 'Desperate Driver',
EE: 'Energetic Elephant'
}
function createJson(str) {
let json = {}
let remainingText = str
while(remainingText.length > 0) {
const tag = remainingText.substring(0, 2)
const len = remainingText.substring(2, 4)
const val = remainingText.substring(4, len)
const offset = tag.length + len.length + parseInt(len, 16)
remainingText = remainingText.substring(offset)
console.log('new text: ' + remainingText)
json[map[tag]] = {}
json[map[tag]][tag] = {}
json[map[tag]][tag][val] = {}
}
return json
}
But this just creates an object that looks like this:
{
Acrobatic Artist: {
AA: {
Claire: {}
}
},
Baddest Banana: {
BB: {
Tom: {}
}
},
Curious Camper: {
CC: {
Jack: {}
}
},
Energetic Elephant: {
EE: {
James: {}
}
}
}
Here is my fiddle:
https://jsfiddle.net/kzaiwo/y9m2h60t/8/
Note:
Please disregard the LASTRECORD part. I just added that to complete the key-value pair (for the last pair) in the above example. Thank you!
Thanks!
If you keep a reference to a prev value, which starts off as the original json object, you can then continuously update it and its children. When you're updating your object within the while loop you can update prev, and set it to the last child object that you create so that on the next iteration of your loop that particular child object will be updated to contain the new key-value pairs.
const map = {
AA: 'Acrobatic Artist',
BB: 'Baddest Banana',
CC: 'Curious Camper',
DD: 'Desperate Driver',
EE: 'Energetic Elephant'
};
const text = 'AA06ClaireCC04JackBB03TomEE05James';
function createJson(str) {
let json = {};
let prev = json;
let remainingText = str;
while (remainingText.length > 0) {
const tag = remainingText.substring(0, 2);
const len = remainingText.substring(2, 4);
const val = remainingText.substring(4, 4 + parseInt(len, 16));
const offset = tag.length + len.length + parseInt(len, 16);
remainingText = remainingText.substring(offset);
prev[map[tag]] = {};
prev[map[tag]][tag] = {};
prev = prev[map[tag]][tag][val] = {};
}
return json;
}
console.log(createJson(text));
Given the regular structure of your string (2-character code + 2-character number + characters), you can use a simple regex to split out the various parts.
From there you can (flat) map each section into an array of keys.
Finally, you can reduce-right the array to produce the result you want.
const map = {AA:"Acrobatic Artist",BB:"Baddest Banana",CC:"Curious Camper",DD:"Desperate Driver",EE:"Energetic Elephant"};
const text = "AA06ClaireCC04JackBB03TomEE05James";
// Parses a code, length and value from the start of the provided string
const parseSection = (str) => {
const [, code, valueLength] = str.match(/^(\w{2})([a-fA-F0-9]{2})/);
const length = parseInt(valueLength, 16) + 4;
return {
code,
length,
type: map[code],
value: str.slice(4, length),
};
};
// Iterates through the string, extracting sections until finished
const parseTlv = (str) => {
const sections = [];
while (str.length) {
const section = parseSection(str);
sections.push(section);
str = str.slice(section.length);
}
return sections;
};
// Map each section to a flat array of keys then reduce-right to form
// a tree structure
const lastRecord = {};
const result = parseTlv(text)
.flatMap(({ type, code, value }) => [type, code, value])
.reduceRight(
(obj, key) => ({
[key]: obj,
}),
lastRecord
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; }
Here is a two part solution:
for() loop: create an array of items based on <tag><len><val> patterns
.reduce(): build the nested object from the items array
const input = 'AA06ClaireCC04JackBB03TomEE05James';
const tagMap = {
AA: 'Acrobatic Artist',
BB: 'Baddest Banana',
CC: 'Curious Camper',
DD: 'Desperate Driver',
EE: 'Energetic Elephant'
};
let items = [];
for(let i = 0; i < input.length; ) {
let tag = input.substring(i, i + 2);
let len = parseInt(input.substring(i + 2, i + 4), 16);
let val = input.substring(i + 4, i + 4 + len);
items.push([tag, val]);
i += 4 + len;
}
let result = {};
items.reduce((obj, arr) => {
const tag = arr[0];
const val = arr[1];
const name = tagMap[tag] || 'unknown';
//console.log(name, tag, val);
[name, tag, val].forEach(key => {
obj[key] = {};
obj = obj[key];
});
return obj;
}, result);
console.log(result);
Output:
{
"Acrobatic Artist": {
"AA": {
"Claire": {
"Curious Camper": {
"CC": {
"Jack": {
"Baddest Banana": {
"BB": {
"Tom": {
"Energetic Elephant": {
"EE": {
"James": {}
}
}
}
}
}
}
}
}
}
}
}
}
Note: the resulting object has an empty {} as the innermost value; you could replace that with "LASTRECORD" if needed
I have an array like
[
"parent1|child1|subChild1",
"parent1|child1|subChild2",
"parent|child2|subChild1",
"parent1|child2|subChild2",
"parent2|child1|subChild1",
"parent2|child1|subChild2",
"parent2|child2|subChild1",
.
.
.
]
Wherein my first string before | is the parent and the second string before | is the child and the third string after the second | is the subchild
How can I convert this array into an object like
[
{
"id": "parent1",
"children":[
{
"id": "child1",
"children":[
{
"id": "subChild1"
}
]
}
]
}
]
Parent -> child -> subchild object
Based on Sebastian's answer I tried below using typescript
private genTree(row) {
let self = this;
if (!row) {
return;
}
const [parent, ...children] = row.split('|');
if (!children || children.length === 0) {
return [{
id: parent,
children: []
}];
}
return [{
id: parent,
children: self.genTree(children.join('|'))
}];
}
private mergeDeep(children) {
let self = this;
const res = children.reduce((result, curr) => {
const entry = curr;
const existing = result.find((e) => e.id === entry.id);
if (existing) {
existing.children = [].concat(existing.children, entry.children);
} else {
result.push(entry);
}
return result;
}, []);
for (let i = 0; i < res.length; i++) {
const entry = res[i];
if (entry.children && entry.children.length > 0) {
entry.children = self.mergeDeep(entry.children);
}
};
return res;
}
private constructTree(statKeyNames){
let self = this;
const res = this.mergeDeep(statKeyNames.map(self.genTree).map(([e]) => e));
console.log(res);
}
but this gives me:
Cannot read property 'genTree' of undefined" error
Update:
As per Sebastian's comment changed self.genTree to this.genTree.bind(this) and it worked without any issues
You could use a mapper object which maps each object to it's unique path (You could map the object with each id, but id is not unique here). Then reduce each partial item in the array. Set the root object as the initialValue. The accumulator will be the parent object for the current item. Return the current object in each iteration.
const input = [
"parent1|child1|subChild1",
"parent1|child1|subChild2",
"parent1|child2|subChild1",
"parent1|child2|subChild2",
"parent2|child1|subChild1",
"parent2|child1|subChild2",
"parent2|child2|subChild1"
],
mapper = {},
root = { children: [] }
for (const str of input) {
let splits = str.split('|'),
path = '';
splits.reduce((parent, id, i) => {
path += `${id}|`;
if (!mapper[path]) {
const o = { id };
mapper[path] = o; // set the new object with unique path
parent.children = parent.children || [];
parent.children.push(o)
}
return mapper[path];
}, root)
}
console.log(root.children)
You have to use recursion for that. Take a look here:
const arr = [
"parent1|child1|subChild1",
"parent1|child1|subChild2",
"parent|child2|subChild1",
"parent1|child2|subChild2",
"parent2|child1|subChild1",
"parent2|child1|subChild2",
"parent2|child2|subChild1"
];
function genTree(row) {
const [parent, ...children] = row.split('|');
if (!children || children.length === 0) {
return [{
id: parent,
children: []
}];
}
return [{
id: parent,
children: genTree(children.join('|'))
}];
};
function mergeDeep(children) {
const res = children.reduce((result, curr) => {
const entry = curr;
const existing = result.find((e) => e.id === entry.id);
if (existing) {
existing.children = [].concat(existing.children, entry.children);
} else {
result.push(entry);
}
return result;
}, []);
for (let i = 0; i < res.length; i++) {
const entry = res[i];
if (entry.children && entry.children.length > 0) {
entry.children = mergeDeep(entry.children);
}
};
return res;
}
const res = mergeDeep(arr.map(genTree).map(([e]) => e));
console.log(JSON.stringify(res, false, 2));
I used two helpers here: genTree(row) which recursively generates a simple tree from each row, and mergeDeep(children) which reduces the first-level trees in the result of arr.map(genTree).map(([e]) => e), and then iterates over the array and recursively does the same thing to all children of each entry.
I am trying to get the value feature_1 of a key name from the array data and set feature_1 as the key of another array asset which has an array as value.
Example :
//input:
data: {
name: "feature_1",
value_a: 1,
value_b: 2
}
//Output:
asset: {
feature_1:[1,2]
}
You can try:
var asset = {};
if ('name' in data) {
var tmp = [];
for (k in data){
if (k != 'name') tmp.push(data[k]);
}
asset[data['name']] = tmp;
}
and in case your interpreter supports ES6 you can use, for example:
let {name, ...v} = data;
let asset = {[name]: Object.values(v)};
If supports same keys in a JSON object ( It seems not ) You can do it like this:
let data= {
name: "feature_1",
value_a: 1,
value_b: 2,
value_x: 500,
name: "feature_2",
value_a: 17,
value_b: 21,
value_x: 510
}
console.log(
Object.entries(data).reduce((a,[key,value],index)=>{
if (key==='name')
return {index, assets: {...a.assets, [value]:[]}};
return {
index : a.index,
assets : {
...a.assets,
[Object.entries(a.assets)[a.index][0]] : [...Object.entries(a.assets)[a.index][1],value]
}};
},{index:0,assets:{}}).assets
);
But we know the correct way is using separated array rows.
This can be accomplished the following way:
const obj = {
data: {
name: "feature_1",
value_a: 1,
value_b: 2
}
};
const output = {
assets: {
[obj.data.name]: Object.values(obj.data).filter(el => el !== obj.data.name)
}
}
console.log(output);
I have a following method, I want to use three variables declared in the 1st three lines instead of checking hard coded values using for loop and add it to res. I was trying following so that I only have to change the values inside successStates & failedStates
// if(successStates.find(x => x === filterVal)){
// filter1 = successStates[0];
// filter2 = successStates[1];
// }
getJobFilter() {
let successStates = ['ACCEPTED_STATE', 'ACTIVE_STATE'];
let failedStates = ['INACTIVE_STATE'];
let otherStates = ['UNKNOWN'];
let res = [];
let filter =
JSON.parse(sessionStorage.getItem('cdgFilter') || '{}');
for (let key in filter) {
if (key) {
if (key === 'collection_status') {
let filterVal: any;
let filter1, filter2;
if (filterVal === "SUCCESSFUL") {
filter1 = 'ACTIVE_STATE';
filter2 = 'ACCEPTED_STATE';
} else if (filterVal === "FAILED") {
filter1 = 'UNKNOWN_STATE';
filter2 = 'INACTIVE_STATE';
}
res.push({
'field': 'State',
'value': filter1
}, {
'field': 'State',
'value': filter2
});
} else {
res.push({
'field': key,
'value': filter[key].filter
});
}
}
}
return res;
}
The easiest way to do this is to use a map object:
const collectionStatusFilters = {
SUCCESSFUL: ['ACTIVE_STATE', 'ACCEPTED_STATE'],
FAILED: ['UNKNOWN_STATE', 'INACTIVE_STATE']
}
You can then replace your if statement thusly:
const filters = collectionStatusFilters[filterVal];
res = res.concat(
filters.map(filter => ({
field: 'State',
value: filter
}))
);
The below code will have input as array of objects and I would like to convert into a different format.
The below code works fine but I need a more refactored shorter format of what I am trying to achieve.
var res = {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"jack1#yahoo.com\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"jack.clinton#yahoo.com\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
var res = [];
for(var key in parsedObj.data){
var emailObj = {};
var phoneObj = {}
if(parsedObj.data[key].email !== null){
emailObj.matchedRes = parsedObj.data[key].email;
emailObj.id = parsedObj.data[key].id;
emailObj.type = "email";
res.push(emailObj);
}
if(parsedObj.data[key].phone !== null){
phoneObj.matchedRes = parsedObj.data[key].phone;
phoneObj.id = parsedObj.data[key].id;
phoneObj.type="phone";
res.push(phoneObj);
}
}
console.log(res);
Desired output:
[ { matchedRes: 'jack1#yahoo.com', id: 'jack1', type: 'email' },
{ matchedRes: 'jack.clinton#yahoo.com', id: 'jack2', type: 'email' },
{ matchedRes: '+16464922600', id: 'jack2', type: 'phone' } ]
In the above code separate objects are created with phone and email for same id.
Here is a solution!
I just did a generic reducer, and then I use it on phone and email.
Then, I just spread the result of both calls to the result array :)
var res = {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"jack1#yahoo.com\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"jack.clinton#yahoo.com\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
const extractData = (obj, type) => obj.reduce((acc, elt) => (
elt[type] && acc.push({matchedRes: elt[type], id: elt.id, type: type})
, acc),[]);
const result = [...extractData(parsedObj.data, 'email'), ...extractData(parsedObj.data, 'phone')];
console.log(result);
Hope this helps, please do not hesitate to comment if you have any question ;)
You can use reduce with destructuring assignment . and check if email or phone is there than add a object accordingly
var res = {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"jack1#yahoo.com\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"jack.clinton#yahoo.com\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
let op = parsedObj.data.reduce((out,{id,email,phone})=>{
if(email){
out.push({matchedRes:email,id,type:`email`})
}
if(phone){
out.push({matchesRes:phone,id,type:`phone`})
}
return out
},[])
console.log(op)
If you want to see more use cases of You can destructuring assignment and it's uses you can check this one out
This should be possible with reduce:
var res = {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"jack1#yahoo.com\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"jack.clinton#yahoo.com\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
const keyFields = ["email", "phone"];
let result = parsedObj.data.reduce((acc, val) => {
keyFields.forEach(k => {
if (val[k]) acc.push({ matchedRes: val.email, id: val.id, type: k});
});
return acc;
}, []);
console.log("Result: ", result);
If you are looking for a little shorter code but still easy to read for anybody:
var res = {"matchObject":"{\"data\":[{\"id\":\"jack1\",\"firstname\":\"jack\",\"lastname\":\"hudson\",\"dob\":\"1990-01-01T00:00:00.000Z\",\"email\":\"jack1#yahoo.com\",\"phone\":null,\"orgid\":\"001\"},{\"id\":\"jack2\",\"firstname\":\"Jack\",\"lastname\":\"Clinton\",\"dob\":\"1991-01-01T00:00:00.000Z\",\"email\":\"jack.clinton#yahoo.com\",\"phone\":\"+16464922600\",\"orgid\":\"002\"}]}"};
var parsedObj = JSON.parse(res.matchObject);
var res = [];
Object.entries(parsedObj.data).forEach(el => {
el = el[1]
if(el.email !== null)
res.push({
matchedRes: el.email,
id: el.id,
type: "email"
})
if(el.phone !== null)
res.push({
matchedRes: el.phone,
id: el.id,
type: "phone"
})
})
console.log(res);