ReactJS Convert json to [name: value:] pair - javascript

I have this json object.
[
{
"crime": "LARCENY-NON_VEHICLE",
"count": "23217"
},
{
"crime": "AUTO_THEFT",
"count": "13675"
},
{
"crime": "LARCENY-FROM_VEHICLE",
"count": "28627"
},
{
"crime": "BURGLARY-RESIDENCE",
"count": "16312"
}
]
I need to display this data in a pie chart so I need to convert it to this format.
[
{name: "LARCENY-NON_VEHICLE", value: 23217},
{name: "AUTO_THEFT", value: 13675},
{name: "LARCENY-FROM_VEHICLE", value: 28627},
{name: "BURGLARY-RESIDENCE", value: 16312}
]
This is how Im retrieving the data using axios.

You can just use map to return a new array with values from old array
const data = [{
"crime": "LARCENY-NON_VEHICLE",
"count": "23217"
},
{
"crime": "AUTO_THEFT",
"count": "13675"
},
{
"crime": "LARCENY-FROM_VEHICLE",
"count": "28627"
},
{
"crime": "BURGLARY-RESIDENCE",
"count": "16312"
}
];
const newData = data.map(item => {
return {
name: item.crime,
value: +item.count // + to convert string to number
}
});
console.log(newData)

You can simply format an array by calling map function
const arr = [
{
crime: "LARCENY-NON_VEHICLE",
count: "23217",
},
{
crime: "AUTO_THEFT",
count: "13675",
},
{
crime: "LARCENY-FROM_VEHICLE",
count: "28627",
},
{
crime: "BURGLARY-RESIDENCE",
count: "16312",
},
];
arr.map((e) => ({
name: e.crime,
count: Number.parseInt(e.count)
}))

Related

How to change object of object of array objects to array objects using javascript

I would like to know how to flatten the array of objects without flap map in javascript
If the of object of arrays object has length greater than 1, flatten
in my example property black has more than object so return that in array of objects
var obj ={
"details": {
"black": [
{
value: 100,
name: "xxx"
},
{
value: 200,
name: "yyy"
}
]
},
"sales": {
"blue": [
{
value: 50,
name: "abc"
}
],
"ALL": [
{
value: 20,
name: "100"
}
]
}
}
Expected Output
[
{
value: 100,
name: "xxx"
},
{
value: 200,
name: "yyy"
}
]
have tried
const result = Object
.values(obj)
.flatMap(v =>
Object.values(v as any)
.filter((group: any) => group.length > 1)
)
without flapmap how to do using javascript
You can create a recursive flatten function using Array.reduce() that takes a multidimensional array, and converts it to a flat array (TS playground):
const obj = {"details":{"black":[{"value":100,"name":"xxx"},{"value":200,"name":"yyy"}]},"sales":{"blue":[{"value":50,"name":"abc"}],"ALL":[{"value":20,"name":"100"}]}}
const flatten = arr =>
arr.reduce((acc, a) => acc.concat(
Array.isArray(a) ? flatten(a) : a
), [])
const result = flatten(Object.values(obj)
.map(v =>
Object.values(v)
.filter(group => group.length > 1)
)
)
console.log(result)
Note: you can also use Array.flat() but since it came out with Array.flatMap() you would probably still have a compatibility problem.
var obj ={
"details": {
"black": [
{
value: 100,
name: "xxx"
},
{
value: 200,
name: "yyy"
}
]
},
"sales": {
"blue": [
{
value: 50,
name: "abc"
}
],
"ALL": [
{
value: 20,
name: "100"
}
]
}
}
console.log(obj.details.black)

New Map from JSON data with unique values

I'm trying to create a new map of [key:value] as [trait_type]:[{values}]
So taking the below data it should look like:
[Hair -> {"Brown", "White-Blue"},
Eyes -> {"Green", "Red"}
]
Heres my json obj
[
{
"name":"Charlie",
"lastname":"Gareth",
"date":1645462396133,
"attributes":[
{
"trait_type":"Hair",
"value":"Brown"
},
{
"trait_type":"Eyes",
"value":"Red"
}
]
},
{
"name":"Bob",
"lastname":"James",
"date":1645462396131,
"attributes":[
{
"trait_type":"Hair",
"value":"White-Blue"
},
{
"trait_type":"Eyes",
"value":"green"
}
]
}
];
To note: I'm also trying to make it the values unique so If I have 2 people with red eyes the value would only ever appear once.
This is what I have so far, kind of works but in the console window the values come out as a char array.
let newData = data.map((item) =>
item.attributes.map((ats) => {
return { [ats.trait_type]: [...ats.value] };
})
);
newData.map((newItem) => console.log(newItem));
You could take an object and iterate the nested data with a check for seen values.
const
data = [{ name: "Charlie", lastname: "Gareth", date: 1645462396133, attributes: [{ trait_type: "Hair", value: "Brown" }, { trait_type: "Eyes", value: "Red" }] }, { name: "Bob", lastname: "James", date: 1645462396131, attributes: [{ trait_type: "Hair", value: "White-Blue" }, { trait_type: "Eyes", value: "green" }] }],
result = data.reduce((r, { attributes }) => {
attributes.forEach(({ trait_type, value }) => {
r[trait_type] ??= [];
if (!r[trait_type].includes(value)) r[trait_type].push(value);
})
return r;
}, {});
console.log(result);
try this
const extractTrait = data =>
data.flatMap(d => d.attributes)
.reduce((res, {
trait_type,
value
}) => {
return {
...res,
[trait_type]: [...new Set([...(res[trait_type] || []), value])]
}
}, {})
const data = [{
"name": "Charlie",
"lastname": "Gareth",
"date": 1645462396133,
"attributes": [{
"trait_type": "Hair",
"value": "Brown"
},
{
"trait_type": "Eyes",
"value": "Red"
}
]
},
{
"name": "Bob",
"lastname": "James",
"date": 1645462396131,
"attributes": [{
"trait_type": "Hair",
"value": "White-Blue"
},
{
"trait_type": "Eyes",
"value": "green"
}
]
}
];
console.log(extractTrait(data))

How to group from array object

I using code form "
I am looking for best ways of doing this. I have group:
data
[
{
"date": "16/04/2020",
"count": 0,
"name": "A"
},
{
"date": "16/04/2020",
"count": 1,
"name": "B"
},
{
"date": "17/04/2020",
"count": 0,
"name": "B"
}
//...More.....
]
Answer
{
"date": "04/2020",
"symtom": {
"data": [
{
"date": "16/04/2020",
"data": [
{
"name": "A",
"count": [
{
"date": "16/04/2020",
"count": 0,
"name": "A"
}
]
},
{
"name": "B",
"count": [
{
"date": "16/04/2020",
"count": 1,
"name": "B"
}
]
},
//...More.....
]
},
{
"date": "17/04/2020",
"data": [
{
"name": "B",
"count": [
{
"date": "17/04/2020",
"count": 0,
"name": "B"
}
]
},
//...More.....
]
}
]
}
}
Can I fix the code and to get the desired answer?
Code :
const items = [
{
tab: 'Results',
section: '2017',
title: 'Full year Results',
description: 'Something here',
},
{
tab: 'Results',
section: '2017',
title: 'Half year Results',
description: 'Something here',
},
{
tab: 'Reports',
section: 'Marketing',
title: 'First Report',
description: 'Something here',
}
];
function groupAndMap(items, itemKey, childKey, predic){
return _.map(_.groupBy(items,itemKey), (obj,key) => ({
[itemKey]: key,
[childKey]: (predic && predic(obj)) || obj
}));
}
var result = groupAndMap(items,"tab","sections",
arr => groupAndMap(arr,"section", "items"));
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
ref : Group array of object nesting some of the keys with specific names
But I would like to have the answer line this (Answer) :
{
"date": "04/2020",
"symtom": {
"data": [
{
"date": "16/04/2020",
"data": [
{
"name": "A",
"count": 0,
},
{
"name": "B",
"count": 1,
},
//...More.....
]
},
{
"date": "17/04/2020",
"data": [
{
"name": "B",
"count":0,
},
//...More.....
]
}
]
}
}
Thanks!
I am a beginner but it looks like you want system.data.data to = an array of objects with the keys name:str and count:number but instead you are applying the whole object into count so the key count:{name:A, count:0,date:etc}.
I really can't follow your function which separates the data... but all you should have to do is when count is sent the object to reference just do a dot notation like object.count to access the number vs the object that way you will have the desired affect. Hopefully that is what you were asking.
I would use a helper function groupBy (this version is modeled after the API from Ramda [disclaimer: I'm one of its authors], but it's short enough to just include here.) This takes a function that maps an object by to a key value, and then groups your elements into an object with those keys pointing to arrays of your original element.
We need to use that twice, once to group by month and then inside the results to group by day. The rest of the transform function is just to format your output the way I think you want.
const groupBy = (fn) => (xs) =>
xs .reduce((a, x) => ({... a, [fn(x)]: [... (a [fn (x)] || []), x]}), {})
const transform = (data) =>
Object .entries (groupBy (({date}) => date.slice(3)) (data)) // group by month
.map (([date, data]) => ({
date,
symtom: {
data: Object .entries (groupBy (({date}) => date) (data)) // group by day
.map (([date, data]) => ({
date,
data: data .map (({date, ...rest}) => ({...rest})) // remove date property
}))
}
}))
const data = [{date: "16/04/2020", count: 0, name: "A"}, {date: "16/04/2020", count: 1, name: "B"}, {date: "17/04/2020", count: 0, name: "B"}, {date: "03/05/2020", count: 0, name: "C"}];
console .log (
transform (data)
)
.as-console-wrapper {min-height: 100% !important; top: 0}
If you need to run in an environment without Object.entries, it's easy enough to shim.
You could take a function for each nested group and reduce the array and the grouping levels.
var data = [{ date: "16/04/2020", count: 0, name: "A" }, { date: "16/04/2020", count: 1, name: "B" }, { date: "17/04/2020", count: 0, name: "B" }],
groups = [
(o, p) => {
var date = o.date.slice(3),
temp = p.find(q => q.date === date);
if (!temp) p.push(temp = { date, symptom: { data: [] } });
return temp.symptom.data;
},
({ date }, p) => {
var temp = p.find(q => q.date === date);
if (!temp) p.push(temp = { date, data: [] });
return temp.data;
},
({ date, ...o }, p) => p.push(o)
],
result = data.reduce((r, o) => {
groups.reduce((p, fn) => fn(o, p), r);
return r;
}, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Javascript Object Tranformation

I am using the map to transforming the JSON. Instead of Single object, I am getting an Array of data.
Snipt Shown Below.
I am trying to achieve following JSON
{
"data": {
"test1": {
"abc": {
"size": "big",
"id": "1"
}
},
"test2": {
"abc": {
"size": "small",
"id": "2"
}
}
}
}
But getting following JSON
{
"data": [{
"test1": {
"abc": {
"size": "big",
"id": "1"
}
}
}, {
"test2": {
"abc": {
"size": "big",
"id": "2"
}
}
}]
}
Here is my code.
const test = [{ id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9',
ad_id: 'test1',
country: 'ID',
abc: { size: 'big', id: '1' },
},
{ id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9',
ad_id: 'test2',
country: 'ID',
abc: { size: 'small', id: '2' },
},
];
const transformedTest = test.map(result =>
({ [result.ad_id]: { abc: result.abc } }));
const data = { data: transformedTest };
console.log(JSON.stringify(data));
Any help will be appreciated
Try this:
const test = [
{
"id": "ddec9c7f-95aa-4d07-a45a-dcdea96309a9",
"ad_id": "test1",
"country": "ID",
"abc": {
"size": "big",
"id": "1"
}
},
{
"id": "ddec9c7f-95aa-4d07-a45a-dcdea96309a9",
"ad_id": "test2",
"country": "ID",
"abc": {
"size": "big",
"id": "2"
}
}
];
const result = test.reduce((acc,{ad_id, abc})=> (acc.data[ad_id] = {abc}, acc),{data:{}})
console.log(result);
const transformedTest = test.reduce((pv, result) =>
({...pv, [result.ad_id]: { abc: result.abc } }), {});
You could take Object.fromEntries and map new key/value pairs and get a new object from it.
const
test = [{ id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9', ad_id: 'test1', country: 'ID', abc: { size: 'big', id: '1' } }, { id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9', ad_id: 'test2', country: 'ID', abc: { size: 'small', id: '2' } }];
transformedTest = Object.fromEntries(test.map(({ ad_id, abc} ) => [ad_id, { abc }]));
data = { data: transformedTest };
console.log(data);
Loop through the array using a simple for...of loop and create a data object. Use Shorthand property names to create the abc nesting:
const test=[{id:'ddec9c7f-95aa-4d07-a45a-dcdea96309a9',ad_id:'test1',country:'ID',abc:{size:'big',id:'1'},},{id:'ddec9c7f-95aa-4d07-a45a-dcdea96309a9',ad_id:'test2',country:'ID',abc:{size:'small',id:'2'}}]
const data = {}
for(const { ad_id, abc } of test) {
data[ad_id] = { abc }
}
console.log({ data })
.as-console-wrapper { min-height: 100%; }
The function map returns an array rather than a specific key-value object, an alternative is using the function reduce to build the desired output.
const test = [{ id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9', ad_id: 'test1', country: 'ID', abc: { size: 'big', id: '1' },},{ id: 'ddec9c7f-95aa-4d07-a45a-dcdea96309a9', ad_id: 'test2', country: 'ID', abc: { size: 'big', id: '2' },}],
data = { data: test.reduce((a, result) =>
({...a, [result.ad_id]: { abc: result.abc } }), Object.create(null))};
console.log(JSON.stringify(data, null, 2));
.as-console-wrapper { min-height: 100%; }

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