How can I convert JSON with nested children to an array whic contain parent_id, Thank you !
var json = {
id: "1",
name: "loreim ipsum",
data: {},
children: [{
id: "2",
name: "lorem ipsum1",
data: {},
children: [{
id: "3",
name: "lorem ipsum2",
data: {},
children: [{
..............
to an array like this
array(
array('id' => 1, 'parent_id' => null, 'name' => 'lorem ipsum'),
array('id' => 2, 'parent_id' => 1, 'name' => 'lorem ipsum1'),
array('id' => 3, 'parent_id' => 1, 'name' => 'lorem ipsum2'),
array('id' => 4, 'parent_id' => 2, 'name' => 'lorem ipsum3'),
array('id' => 5, 'parent_id' => 3, 'name' => 'lorem ipsum4'),
array('id' => 6, 'parent_id' => null, 'name' => 'lorem ipsum5'),
);
Recursively build a flat array -
var json = {
id: "1",
name: "loreim ipsum",
data: {},
children: [{
id: "2",
name: "lorem ipsum1",
data: {},
children: [{
id: "3",
name: "lorem ipsum2",
data: {},
children: [{
id: "4",
name: "lorem ipsum2",
data: {}
}]
},
{
id: "5",
name: "lorem ipsum2",
data: {},
children: [{
id: "6",
name: "lorem ipsum2",
data: {}
}]
}
]
}]
}
function flat(array, parentId) {
var result = [];
array.forEach(function(a) {
var newObject = Object.assign({}, a);
delete newObject.children;
newObject.parent_id = parentId;
result.push(newObject);
if (Array.isArray(a.children)) {
result = result.concat(flat(a.children, a.id));
}
});
return result;
}
console.log(flat([json], null));
Related
I have an array called data. How do i extract sub_data? Just need the sub_data part for each object.
const data = [
{
id: 1,
title: 'Logo'
sub_data: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands'
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
Example output will get two outputs because there is 2 objects:
const subData = [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
const subData = [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
Not very sure how to use the map function just to get sub_data in the correct structure
You can use flatMap to get sub_data in one array
const data = [
{
id: 1,
title: 'Logo',
sub_data: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands',
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
const result = data.flatMap(item => item.sub_data)
console.log(result)
If you want an array with the sub_data objects you can just map the original array:
const data = [
{
id: 1,
title: 'Logo',
'sub_data'
: [
{
id: 2,
title: 'Company Logo'
},
{
id: 3,
title: 'Website Logo'
},
]
},
{
id: 2,
title: 'Brands',
sub_data: [
{
id: 25,
title: 'Company Brands'
},
{
id: 3,
title: 'Website Brands'
},
]
}
]
const mappedData = data.flatMap(obj => obj.sub_data)
console.log(mappedData)
Another solution would be to use the .forEach function of javascript.
const subData = [];
data.forEach(item => subData.push(...item.sub_data))
I have JSON data that looks like this:
[
{
"id": 1,
"tags": [
"Test 1",
"Test 2",
"Test 3"
]
},
{
"id": 2,
"tags": [
"Test 2",
"Test 3",
"Test 4"
]
},
{
"id": 3,
"tags": [
"Test 3",
"Test 4"
]
}
]
I would like to transform this into data that looks like this:
[
{
"name": "Test 1",
"count": 1
},
{
"name": "Test 2",
"count": 2
},
{
"name": "Test 3",
"count": 3
},
{
"name": "Test 4",
"count": 1
}
]
I can think of some brute ways to do this, but I'm hoping there is something more performant and a little sexier? Possibly using .groupBy() or .reduce()?
Thanks for taking the time to check out my question.
I would:
parse the json
gather all tags in an array
count occurences using one of the approaches in Counting the occurrences / frequency of array elements
interface Item {
id: number,
tags: string[]
}
function countOccurences(a: string[]) {
return a.reduce(function (acc: {[key: string]: number}, curr: string) {
acc[curr] ??= 0;
acc[curr]++;
return acc;
}, {});
}
const data: Item[] = JSON.parse(json);
const tagOccurences = countOccurences(data.flatMap(o => o.tags))
Playground link
You can use reduce inside reduce to group the tags.
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {}
));
console.log(frequencies);
In TypeScript:
const array = [{
id: 1,
tags: ['Test 1', 'Test 2', 'Test 3'],
},
{
id: 2,
tags: ['Test 2', 'Test 3', 'Test 4'],
},
{
id: 3,
tags: ['Test 3', 'Test 4'],
},
];
type Frequency = {
name: string,
count: number
}
const frequencies = Object.values(array.reduce((acc, curr) =>
curr.tags.reduce(
(nAcc, tag) => ((nAcc[tag] ??= {name: tag,count: 0}),nAcc[tag].count++,nAcc),
acc
), {} as Record<string, Frequency>
));
console.log(frequencies);
Playground
Using for...of iteration and a Map as a cache is a very straightforward approach... and sexy.
TS Playground
type TagsWithId = {
id: number;
tags: string[];
};
type TagCount = {
count: number;
name: string;
};
function verySexyTagCounter (input: TagsWithId[]): TagCount[] {
const map = new Map<string, number>();
for (const {tags} of input) {
for (const name of tags) {
map.set(name, (map.get(name) ?? 0) + 1);
}
}
return [...map.entries()].map(([name, count]) => ({name, count}));
}
const json = `[{"id":1,"tags":["Test 1","Test 2","Test 3"]},{"id":2,"tags":["Test 2","Test 3","Test 4"]},{"id":3,"tags":["Test 3","Test 4"]}]`;
const input: TagsWithId[] = JSON.parse(json);
const result = verySexyTagCounter(input);
console.log(result);
I have two objects:
Object 1:
{[ 'Managers', 'Employee', '50% Discount', undefined, 'Managers', undefined ]}
Object 2:
{[ { id: 3, name: 'Managers', transaction_modifier: 1 },
{ id: 4, name: 'Employee', transaction_modifier: 1.1 },
{ id: 12, name: '50% Discount', transaction_modifier: 0.5 } ]}
I need to compare both objects and create a new one:
if Object 1 match Object 2's name return
{id: objectID, name: ObjectName, transaction_modifier: ObjectTransaction_modifier}
if object one is undefined or name not in Object 2 return
{id: null, name: null, transaction_modifier: 1}
In this example I expect to return the following object:
[ { id: 3, name: 'Managers', transaction_modifier: 1 },
{ id: 4, name: 'Employee', transaction_modifier: 1.1 },
{ id: 12, name: '50% Discount', transaction_modifier: 0.5 },
{ id: null, name: null, transaction_modifier: 1 },
{ id: 3, name: 'Managers', transaction_modifier: 1 },
{ id: null, name: null, transaction_modifier: 1 }]
Try
const fields = [ 'Managers', 'Employee', '50% Discount', undefined, 'Managers', undefined ];
const data = [ { id: 3, name: 'Managers', transaction_modifier: 1 },
{ id: 4, name: 'Employee', transaction_modifier: 1.1 },
{ id: 12, name: '50% Discount', transaction_modifier: 0.5 } ];
console.log(fields.map(field => data.find(entry => entry.name === field) || ({id: null, name: null, transaction_modifier: 1})));
I'm setting up an array of list, and want to parse the value from JSON to that list
This is the array
const universityOptions = [
{ key: '1', text: 'Universtiy 1', value: 'Universtiy 1' },
{ key: '2', text: 'Universtiy 2', value: 'Universtiy 2' },
{ key: '3', text: 'Universtiy 3', value: 'Universtiy 3' },
{ key: '4', text: 'Universtiy 4', value: 'Universtiy 4' },
{ key: '5', text: 'Universtiy 5', value: 'Universtiy 5' },
{ key: '6', text: 'Universtiy 6', value: 'Universtiy 6' }
]
Below is the json
{"success":true,"data":[{"id":1,"name":"University 1"},{"id":2,"name":"University 2"},{"id":3,"name":"University 3"},{"id":4,"name":"University 4"},{"id":5,"name":"University 5"},{"id":6,"name":"University 6"}]}
and this is the method i tried so far, which i get the data but i only need the data.name (university name) and i'm stuck how to get it
componentDidMount() {
const univFetch = fetch('url')
// university_list state
univFetch.then(res => {
if( res.status === 200)
return res.json()
}).then( univJson => {
this.setState({
university_list: univJson.data
})
console.log(univJson.data);
})
}
Result
(6) [{…}, {…}, {…}, {…}, {…}, {…}]
0: {id: 1, name: "University 1"}
1: {id: 2, name: "University 2"}
2: {id: 3, name: "University 3"}
3: {id: 4, name: "University 4"}
4: {id: 5, name: "University 5"}
5: {id: 6, name: "University 6"}
length: 6
__proto__: Array(0)
I expect the output is an array like
const universityOptions = [
{ key: '1', text: 'Universtiy 1', value: 'Universtiy 1' },
{ key: '2', text: 'Universtiy 2', value: 'Universtiy 2' },
{ key: '3', text: 'Universtiy 3', value: 'Universtiy 3' },
{ key: '4', text: 'Universtiy 4', value: 'Universtiy 4' },
{ key: '5', text: 'Universtiy 5', value: 'Universtiy 5' },
{ key: '6', text: 'Universtiy 6', value: 'Universtiy 6' }
]
Thanks
Try it like this:
const newArray = json.data.map(elem => ({
key: elem.id.toString(),
text: elem.name,
value: elem.name
}));
Your componentDidMount() would end up being something like this:
componentDidMount() {
const univFetch = fetch('url')
univFetch.then(res => {
if( res.status === 200)
return res.json()
}).then( univJson => {
const universityList = univJson.data.map(elem => ({
key: elem.id.toString(),
text: elem.name,
value: elem.name
}));
this.setState({
university_list: universityList
})
})
}
Here's the Sandbox if you want to take a look at it. Hope it helps.
You need to iterate over your response and you can create desired output like this,
this.setState({
university_list : univJson.data.map(data => ({key:data.id,text:data.name,value:data.name}))
}, ()=>console.log(this.state.university_list))
Error is use forEach on univJson and create an array
componentDidMount() {
const univFetch = fetch('url')
// university_list state
univFetch.then(res => {
if( res.status === 200)
return res.json()
}).then( univJson => {
let univArray = [];
univJson.forEach((datum, index) => {
univArray.push({ key: datum.id, text: datum.name, value: datum.name});
})
this.setState({
university_list: univArray
})
console.log(univJson.data);
})
}
Why not perform an extra operation,
componentDidMount() {
const univFetch = fetch('url')
// university_list state
univFetch.then(res => {
if( res.status === 200)
return res.json()
}).then( univJson => {
var output = [];
for(var i=0 ;i<univJson.data;i++){
var obj = {key : univJson.data[i]["id"],
text : univJson.data[i]["name"],
value : univJson.data[i]["name"]
}
output.push(obj)
}
this.setState({
university_list: output
});
console.log(output);
})
}
I need to implement tree table in my react application. that has grouped by an object property value.
The object is as follows
{
"SP": [
{
"DisplayName": "audi",
"Name": "r8",
"Type": "2012"
},
{
"DisplayName": "audi",
"Name": "rs5",
"Type": "2013"
}
],
"Code": [
{
"DisplayName": "ford",
"Name": "mustang",
"Type": "2012"
},
{
"DisplayName": "ford",
"Name": "fusion",
"Type": "2015"
}
],
"Message": [
{
"DisplayName": "kia",
"Name": "optima",
"Type": "2012"
}
]
}
And my table should be as the following image
I have used antd in my project and I tried to implement this functionality with antd table and could not implement as I want. I need the filter functionality too.
Can anyone suggest a solution
You need to restructure your dataSource witch children prop:
function NestedTables() {
return (
<Flexbox>
<Table
size="small"
indentSize={0}
columns={columns}
dataSource={source}
/>
</Flexbox>
);
}
When your source is:
const source = [
{
key: '1',
Code: 'SP',
children: [
{
key: '11',
Code: '5001',
DisplayName: 'audi',
Name: 'r8',
Type: '2012'
},
{
key: '12',
Code: '313',
DisplayName: 'audi',
Name: 'rs5',
Type: '2013'
}
]
},
{
key: '2',
Code: 'Code',
children: [
{
key: '21',
Code: '243',
DisplayName: 'ford',
Name: 'mustang',
Type: '2012'
},
{
key: '22',
Code: '503431',
DisplayName: 'ford',
Name: 'fusion',
Type: '2015'
}
]
},
{
key: '3',
Code: 'Message',
children: [
{
key: '31',
Code: '4311',
DisplayName: 'kia',
Name: 'optima',
Type: '2012'
}
]
}
];
And defined columns filters:
const columns = [
{
title: 'Code',
dataIndex: 'Code',
key: 'Code',
filters: [
{ text: 'SP', value: 'SP' },
{ text: 'Code', value: 'Code' },
{ text: 'Message', value: 'Message' }
],
onFilter: (value, record) => record.Code.indexOf(value) === 0
},
{
title: 'Display Name',
dataIndex: 'DisplayName',
key: 'DisplayName',
filters: [
{ text: 'audi', value: 'audi' },
{ text: 'ford', value: 'ford' },
{ text: 'kia', value: 'kia' }
],
onFilter: (value, record) =>
record.children.filter(child => child.DisplayName === value).length > 0
},
{ title: 'Name', dataIndex: 'Name', key: 'Name' },
{ title: 'Type', dataIndex: 'Type', key: 'Type' }
];
Demo: