separate json object into different index - javascript

I have following array which consist of json objects:
items = [
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-10',
creditAmount: '200',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-14',
creditAmount: '159',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-15',
creditAmount: '3421',
numberBank: '12345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-15',
creditAmount: '6000',
numberBank: '13345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-16',
creditAmount: '6565',
numberBank: '13345',
}
]
I want to separate the array index for each same id
as an example :
[
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-10',
creditAmount: '200',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-14',
creditAmount: '159',
numberBank: '12345',
},
{
id: '1',
name: 'Josh',
transactionDate: '2012-08-15',
creditAmount: '3421',
numberBank: '12345',
}
],
[
{
id: '2',
name: 'George',
transactionDate: '2012-09-15',
creditAmount: '6000',
numberBank: '13345',
},
{
id: '2',
name: 'George',
transactionDate: '2012-09-16',
creditAmount: '6565',
numberBank: '13345',
}
]
How to do like that ? thanks

you can use reduce to group by id and then the values of the resultant using Object.values
EDIT
??= is the Logical nullish assignment. The right hand side will be assigned whenever the left hand side is null or undefined.
let items = [ { id: '1', name: 'Josh', transactionDate: '2012-08-10', creditAmount: '200', numberBank: '12345', }, { id: '1', name: 'Josh', transactionDate: '2012-08-14', creditAmount: '159', numberBank: '12345', }, { id: '1', name: 'Josh', transactionDate: '2012-08-15', creditAmount: '3421', numberBank: '12345', }, { id: '2', name: 'George', transactionDate: '2012-09-15', creditAmount: '6000', numberBank: '13345', }, { id: '2', name: 'George', transactionDate: '2012-09-16', creditAmount: '6565', numberBank: '13345', } ]
const res = Object.values(items.reduce((acc,curr)=> {
acc[curr.id]??=[] //similar to acc[curr.id] = acc[curr.id] || [] in this case
acc[curr.id].push(curr)
return acc
},{}))
console.log(res)

Related

Filter and find properties in array of objects

This code is working but i would like to make it with array methods. The condition of filtering is: if programParent is empty string -> must pass, if id equals to some programParent -> must pass. I was trying to make it with filter method and find, but i need some help. Thanks in advance.
let programsRes = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
{ id: '28', name: 'Ad Hoc asd', programParent: '27' },
{ id: '29', name: 'Ad Hoc 123', programParent: '27' },
{ id: '30', name: 'ventas IN Personal plus', programParent: '26' },
]
let expected = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
]
let result = []
for (let i = 0; i < programsRes.length; i++) {
for (let j = 0; j < programsRes.length; j++) {
if (programsRes[i].programParent === '') {
result.push(programsRes[i])
break;
}
if (programsRes[i].id === programsRes[j].programParent) {
result.push(programsRes[i])
break;
}
}
}
console.log(result)
let programsRes = [
{ id: '23', name: 'ventas', programParent: '' },
{ id: '24', name: 'ventas OUT Personal', programParent: '23' },
{ id: '25', name: 'ventas OUT Personal plus', programParent: '24' },
{ id: '26', name: 'ventas IN Hogares', programParent: '23' },
{ id: '27', name: 'Ad Hoc', programParent: '' },
{ id: '28', name: 'Ad Hoc asd', programParent: '27' },
{ id: '29', name: 'Ad Hoc 123', programParent: '27' },
{ id: '30', name: 'ventas IN Personal plus', programParent: '26' },
];
let result = programsRes.filter(program =>
program.programParent === '' ||
programsRes.some(item => item.programParent === program.id));
console.log(result)

How to create table with title in React native

I want to create a Table in React native like the below image
TABLE PICTURE🔽🔽🔽🔽🔽
i have two JSON data
tableTitle.json
var tableTitle = [
{ id: '11', last_nom: 'Cars'},
{ id: '12', last_nom: 'Phones'}
];
tableInfo.json
var tableInfo = [
{ id: '1', parent_id: '11', name: 'toyota', model:'camry', year:'2020', country:'japan'},
{ id: '2', parent_id: '11', name: 'huyndai', model:'accent', year:'2018', country:'s.korea'},
{ id: '3', parent_id: '11', name: 'tesla', model:'s30', year:'2022', country:'usa'},
{ id: '4', parent_id: '12', name: 'iphone', model:'14 pro', year:'2020', country:'usa'},
{ id: '5', parent_id: '12', name: 'samsung', model:'ss22', year:'2018', country:'s.korea'},
{ id: '6', parent_id: '12', name: 'pixel', model:'4', year:'2022', country:'usa'},
];
Get table title
useEffect(()=>{
const config = {
method:'get',
url: `http://URL.COM/${id}`,
headers: { }
}
axios(config)
.then(function(response){
let info = response.data
let newArray = info.map((list)=>{
return {id: list.id, name: list.name}
})
setTitle(newArray)
// console.log(newArray)
})
.catch(function (error) {
console.log(error);
})
})

How to group by array of objects

I have an array of objects like the below:
const data = [{label: 'ABC', id: '1', emp:{empLabel: 'Test1', empId: '12'}},
{label: 'ABC', id: '1', emp:{empLabel: 'Test2', empId: '13'}},
{label: 'DEF', id: '2', emp:{empLabel: 'Test11', empId: '14'}},
{label: 'DEF', id: '2', emp:{empLabel: 'Test12', empId: '15'}},
{label: 'PQR', id: '3', emp:{empLabel: 'Test13', empId: '16'}},
{label: 'XYZ', id: '4', emp:{empLabel: 'Test14', empId: '17'}}
]
I am trying to club the emp data if my id is equal.
Expected Output:
[
{label: 'ABC', id: '1', emp:[{empLabel: 'Test1', empId: '12'}, {empLabel: 'Test2', empId: '13'}]},
{label: 'DEF', id: '2', emp:[{empLabel: 'Test11', empId: '14'}, {empLabel: 'Test12', empId: '15'}]},
{label: 'PQR', id: '3', emp:{empLabel: 'Test13', empId: '16'}},
{label: 'XYZ', id: '4', emp:{empLabel: 'Test14', empId: '17'}}
]
I have tried to do this by lodash but am not sure how to proceed after this. Any help would appreciate?
My Approach:
result = _.map(data, eachData => {
return _.chain(_.flatMap(eachData))
})
const _ = require("lodash")
let items = [
{ label: 'ABC', id: '1', emp: { empLabel: 'Test1', empId: '12' } },
{ label: 'ABC', id: '1', emp: { empLabel: 'Test2', empId: '13' } },
{ label: 'DEF', id: '2', emp: { empLabel: 'Test11', empId: '14' } },
{ label: 'DEF', id: '2', emp: { empLabel: 'Test12', empId: '15' } },
{ label: 'PQR', id: '3', emp: { empLabel: 'Test13', empId: '16' } },
{ label: 'XYZ', id: '4', emp: { empLabel: 'Test14', empId: '17' } }
]
var result = _(items)
.groupBy('id')
.map(function(items, label) {
return {
label: label,
emp: _.map(items, 'emp')
};
}).value();
console.log("result -> ", result)
This works, unless you are specifically trying to use lodash:
const result = data.reduce((acc, val) => {
const existingGroup = acc.find((group) => val.id === group.id);
if(!!existingGroup) {
if(existingGroup.emp && Array.isArray(existingGroup.emp)) {
existingGroup.emp = [...existingGroup.emp, val.emp];
} else {
existingGroup.emp = [existingGroup.emp, val.emp]
}
} else {
acc = [...acc, val];
}
return acc;
},[]);
console.log(result);
Try using array.filter(). Do something like
ar = []
let newarr = []
data.map(x => if (ar.indexOf(x)===-1) {newarr.push(x); at.push(x.id))
newArr is now your array.

JavaScript group data into tree view 2 levels deep

I have a JSON object like this:
{
id: '1',
items: [
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
},
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}
]
},
{
id: '2',
items: [
{
id: '2',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '556',
categoryDescription: 'my category 6',
qty: 10,
saleValue: 200
}
]
},
{
id: '3',
items: [
{
venueId: '3',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '557',
categoryDescription: 'my category 7',
qty: 10,
saleValue: 200
}
]
};
I want to make this into a new JSON object where everything is grouped by id (it already is but I need the number to become the key) then by categoryCode so the result looks something like this:
{
'1': {
'555': {
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}
}
}
Is there a simple way to do this either using lodash or just plain JavaScript or some NPM package?
I create a general function that receiving array of items and parse it based on attrKeys and infoKeys array:
const data = [{
id: '1',
items: [{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}, {
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}]
}, {
id: '2',
items: [{
id: '2',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '556',
categoryDescription: 'my category 6',
qty: 10,
saleValue: 200
}]
}, {
id: '3',
items: [{
venueId: '3',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '557',
categoryDescription: 'my category 7',
qty: 10,
saleValue: 200
}]
}];
const transformData = (input, attrKeys = [], infoKeys = [], deep = 0) => {
if (input && typeof input === 'object' && input.length) {
const key1 = attrKeys[deep];
const key2 = infoKeys[deep];
deep++;
const output = {}
input.forEach(i => {
const info = i[key2] ? transformData(i[key2], attrKeys, infoKeys, deep) : i;
output[`${i[key1]}`] = info;
});
return output;
}
return input;
};
//What you want is here
const transformedData = transformData(data, ['id','categoryCode'], ['items'])
console.log({transformedData})
Follow the nested for...of loop approach:
const data = [{
id: '1',
items: [{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}, {
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}]
}, {
id: '2',
items: [{
id: '2',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '556',
categoryDescription: 'my category 6',
qty: 10,
saleValue: 200
}]
}, {
id: '3',
items: [{
venueId: '3',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '557',
categoryDescription: 'my category 7',
qty: 10,
saleValue: 200
}]
}];
let finalData = {};
for (let obj of data) {
finalData[obj.id] = {};
for (var item of obj.items) {
finalData[obj.id][item.categoryCode] = { ...item
};
}
}
console.log(finalData);
You can use Array.reduce function to achieve it.
const array = [{
id: '1',
items: [
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
},
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}
]
},
{
id: '2',
items: [
{
id: '2',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '556',
categoryDescription: 'my category 6',
qty: 10,
saleValue: 200
}
]
},
{
id: '3',
items: [
{
id: '3',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '557',
categoryDescription: 'my category 7',
qty: 10,
saleValue: 200
}
]
}];
console.log(
array
// flatten the items array
.reduce((prev, curr) => {
return prev.concat(curr.items);
}, [])
.reduce((prev, curr) => {
if (!prev[curr.id])
prev[curr.id] = {};
if (!prev[curr.id][curr.categoryCode])
prev[curr.id][curr.categoryCode] = {};
prev[curr.id][curr.categoryCode] = curr;
return prev;
}, {})
);
Alternatively, you can archive that by just 7 lines of code using reduce function.
const array = [
{
id: '1',
items: [
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
},
{
id: '1',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '555',
categoryDescription: 'my category',
qty: 10,
saleValue: 200
}
]
},
{
id: '2',
items: [
{
id: '2',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '556',
categoryDescription: 'my category 6',
qty: 10,
saleValue: 200
}
]
},
{
id: '3',
items: [
{
venueId: '3',
saleId: '123',
saleIdAndItemId: '123456',
locationId: '123',
itemCode: '456',
itemDescription: 'my item',
categoryCode: '557',
categoryDescription: 'my category 7',
qty: 10,
saleValue: 200
}
]
}
];
console.log(
array.reduce((prev, curr) => {
prev[curr.id] = curr.items.reduce((prev, curr) => {
(prev[curr.categoryCode] = []).push(curr);
return prev;
}, {});
return prev;
}, {})
);

Mapping array of objects to array of arrays with headers using ES6

I want to map an array of objects, which I got from a json response of my backend, to an array of arrays, with the first row being an array of headers (titles). I'll use this array to make it downloadable in a csv file.
Also, I want to keep away a couple of headers / columns that are not really interesting for the end user to have in their csv file.
My code is working fine, but I have the idea that it can be done with more concise code. I'm fine with using ES6 / ES2015, but not really experienced with spread syntax and other ES6 goodies myself, so any suggestions for a better, more modern (functional / reactive?) approach are greatly appreciated.
const originalData = [
{name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
]
let headers = []
const firstRow = originalData[0]
for (var key in firstRow) {
if (firstRow.hasOwnProperty(key)) {
if (!['raw','updated_at'].includes(key)) {
headers.push(key)
}
}
}
const d = originalData.map(function(_, i) {
return headers.map(function(header) {
return originalData[i][header]
}.bind(this))
}.bind(this))
const result = [headers].concat(d)
console.log(result)
Something like this?
const originalData = [
{ name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping' },
{ name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail' },
{ name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing' }
]
const headers = Object.keys(originalData[0]).filter(key => !['raw', 'updated_at'].includes(key));
const d = originalData.map(obj => headers.map(key => obj[key]))
const result = [headers, ...d];
console.log(result)
Basically you could use a closure over the filtered keys and map and concat the arrays.
const fn = (array => (keys => [keys].concat(array.map(o => keys.map(k => o[k]))))
(Object.keys(array[0]).filter(k => !['raw','updated_at'].includes(k)))),
data = [{ name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping' }, { name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail' }, { name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing' }],
result = fn(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
const originalData = [
{name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
];
const propertiesNeeded = Object.keys(originalData[0]).filter(prop => !['raw', 'updated_at'].includes(prop));
const dataMapped = originalData.map(obj => propertiesNeeded.map(prop => obj[prop]));
const finalArr = [propertiesNeeded, ...dataMapped];
This is how I'd do it. I figured if you know which keys you're after then we can make good use of that.
const data = [
{name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
]
const desiredKeys = ['name', 'species', 'age', 'skill']
const result = [desiredKeys].concat(data.map(pet => desiredKeys.map(key => pet[key])))
console.log(result)
Yours is good. You could simplify the header creation by using Object.keys
const originalData = [
{name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
]
const headers = Object.keys(originalData[0])
.filter(key => !['raw','updated_at'].includes(key)));
const data = originalData.map(row => headers.map(header => row[header]));
console.log(headers, data);
Try with Array#map used for recreate the array with Object.key and value . and new Set() method user for create the key set value .ignore the repeated one ... its spread syntax
const originalData = [
{name: 'Gizmo', species: 'cat', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
]
var result = [[...new Set(...originalData.map(a=> Object.keys(a)))]].concat(originalData.map(a=> Object.values(a)))
console.log(result)
.as-console-wrapper { max-height: 100% !important; top: 0; }
A single line of code in an unbroken chain using a filter and reduce.
var unborken = chain => chain.filter((_, i, xx) =>
delete xx[i].updated_at && delete xx[i].raw).reduce((aac, _, i, aa) =>
(i === 0 ? aac.push(Object.keys(aa[i])) && aac.push(Object.values(aa[i])) :
aac.push(Object.values(aa[i])), aac), []);
const originalData = [{
name: 'Gizmo',
species: 'cat',
age: '9',
raw: 'G9e76rd',
updated_at: '1318874398806',
skill: 'sleeping'
},
{
name: 'Benny',
species: 'dog',
age: '3',
raw: '98HDo2h',
updated_at: '1318874392417',
skill: 'chasing tail'
},
{
name: 'Oscar',
species: 'cat',
age: '2',
raw: '9da8Ro1',
updated_at: '1318874390283',
skill: 'meowing'
}
];
console.log(unborken(originalData));
.as-console-wrapper { max-height: 100% !important; top: 0; }
I'd like to point out that an object's keys order is not entirely "fixed" by spec.
If your first animal in your originalData starts with a species property, your whole table will be formatted in that column order...
Therefore I'd advice you to explicitly define your columns in an array, in which order does matter.
Note that in the example below I've swapped the property declaration order of Gizmo. Put this data in your own code and the first column will be species. (at least in my browser it is, I guess it can even differ between browsers?)
const data = [
{species: 'cat', name: 'Gizmo', age: '9', raw: 'G9e76rd', updated_at: '1318874398806', skill: 'sleeping'},
{name: 'Benny', species: 'dog', age: '3', raw: '98HDo2h', updated_at: '1318874392417', skill: 'chasing tail'},
{name: 'Oscar', species: 'cat', age: '2', raw: '9da8Ro1', updated_at: '1318874390283', skill: 'meowing'}
]
const getProps = props => obj =>
props.map(k => obj[k]);
const columns = ["name", "species", "age", "skill"];
console.log(
[columns, ...data.map(getProps(columns))]
);

Categories