Efficient Way to Iterate and Producing Output in Javascript/React - javascript

I have following datas,
let response =[
{
"14714733": [
"Android Testing-1",
"Test special manual",
"Test Manual",
"SECESC"
]
},
{
"10110133": [
"Android Testing-1",
"SECESC"
]
}
]
let shipment =[
{
"masterDocumentNumber": "14714733"
},
{
"masterDocumentNumber": "10110133",
}
]
And
let flagIns=[
{
"fieldValue": "SECESC",
"fieldDescription": "Security Escort"
},
{
"fieldValue": "INS",
"fieldDescription": "Inspection"
}
]
How to iterate and add Corresponding response data in to shipment data as follows,
Desired output
let shipment =[
{
"masterDocumentNumber": "14714733",
"instructions":[
{"index":0,"instruction":"Android Testing-1"},
{"index":1,"instruction":"Test special manual"},
{"index":2,"instruction":"Test Manual"},
{"index":3,"instruction":"Security Escort"}
]
},
{
"masterDocumentNumber": "10110133",
"instructions":[
{"index":0,"instruction":"Android Testing-1"},
{"index":1,"instruction":"Security Escort"}
]
}
]
Note that if flagIns has same data in response then it need to be replaced with it's description.

You should be able to use a function similar to this.. it appears you just need to match up keys and values from the different objects..
function aggregate(response, shipment, flagIns) {
return shipment.map(({ masterDocumentNumber }) => {
let output = { masterDocumentNumber, instructions: [] }
let res = response.find(r => masterDocumentNumber in r);
if (res) {
res[masterDocumentNumber].forEach((r, i) => {
let ins = flagIns.find(fi => fi.fieldValue === r);
output.instructions.push({
index: i,
instruction: ins ? ins.fieldDescription : r
})
})
}
return output;
});
}
const response = [
{
"14714733": [
"Android Testing-1",
"Test special manual",
"Test Manual",
"SECESC"
]
},
{
"10110133": ["Android Testing-1", "SECESC"]
}
];
const shipment = [
{
masterDocumentNumber: "14714733"
},
{
masterDocumentNumber: "10110133"
}
];
const flagIns = [
{
fieldValue: "SECESC",
fieldDescription: "Security Escort"
},
{
fieldValue: "INS",
fieldDescription: "Inspection"
}
];
console.log(aggregate(response, shipment, flagIns));

let shipment =[];
//create array
response.map((res)=>{
//get keys
let key=Object.keys(res)
//loop in instructions
let instructions=[];
res[key].map((val,i)=>{
let inst ={
"index":i,
"instruction":val
}
instructions.push(inst)
})
let m={
"masterDocumentNumber":key,
"instructions":instructions
}
shipment.push(m)
})
console.log(JSON.stringify(shipment))

First flatten the response and flagIns array of objects and then iterate over the shipment array to get the desired output.
let response =[
{
"14714733": [
"Android Testing-1",
"Test special manual",
"Test Manual",
"SECESC"
]
},
{
"10110133": [
"Android Testing-1",
"SECESC"
]
}
]
let shipment =[
{
"masterDocumentNumber": "14714733"
},
{
"masterDocumentNumber": "10110133",
}
]
let flagIns=[
{
"fieldValue": "SECESC",
"fieldDescription": "Security Escort"
},
{
"fieldValue": "INS",
"fieldDescription": "Inspection"
}
]
const responseRes = response.reduce(function (acc, item) {
return Object.assign(acc, item);
}, {});
// responseRes
// {
// '10110133': [ 'Android Testing-1', 'SECESC' ],
// '14714733': [
// 'Android Testing-1',
// 'Test special manual',
// 'Test Manual',
// 'SECESC'
// ]
// }
const flagInsRes = flagIns.reduce(function (acc, item) {
return Object.assign(acc, {
[item.fieldValue]: item.fieldDescription});
}, {});
// flagInsRes
// { SECESC: 'Security Escort', INS: 'Inspection' }
const shipmentRes = shipment.map(obj => {
const temp = {};
temp.masterDocumentNumber = obj.masterDocumentNumber
temp.instructions = responseRes[obj.masterDocumentNumber]
.map((item, index) => {
return {
"index":index,
"instruction":flagInsRes[item] ? flagInsRes[item] : item}
});
return temp;
});
console.log(shipmentRes);

Related

How to flatten nested array of objects and create new array

I have a data structure as the following
[
{
"models":[
{
"name":"xyz",
"options":[
{
"label":"blue"
},
{
"label":"brown"
},
]
},
{
"name":"abc",
"options":[
{
"label":"yellow"
}
]
},
{
"name":"def",
"options":[
{
"label":"green"
}
]
}
]
}
]
The end result should be an array with all of the labels and name like xyz: blue, xyz: brown, abc: yellow, def: green
so something like this
['xyz: blue', 'xyz: brown', 'abc: yellow','def: green']
I'm trying different approaches, one with RxJS operators and another with reduce
let flat = (acc, current) => {
}
models.reduce(flat, [])
You can use a reduce and a map like this.
const arr = [
{
"models":[
{
"name":"xyz",
"options":[
{
"label":"blue"
},
{
"label":"brown"
},
]
},
{
"name":"abc",
"options":[
{
"label":"yellow"
}
]
},
{
"name":"def",
"options":[
{
"label":"green"
}
]
}
]
}
];
const result = arr[0].models.reduce(
(acc, model) => [...acc, ...model.options.map(i => ({ [model.name]: i.label }))]
, []
);
console.log(result);
If the top level array can have multiple items rather than arr[0] you would need to add another reduce feeding it's accumulator in to the second reduce as it's starting accumulator rather than the empty starting array.
const arr = [
{
"models":[
{
"name":"xyz",
"options":[
{
"label":"blue"
},
{
"label":"brown"
},
]
},
{
"name":"abc",
"options":[
{
"label":"yellow"
}
]
},
{
"name":"def",
"options":[
{
"label":"green"
}
]
}
]
},
{
"models":[
{
"name":"ghi",
"options":[
{
"label":"gold"
},
{
"label":"pink"
},
]
}
]
}
];
const result = arr.reduce(
(acc, item) =>
item.models.reduce(
(acc2, model) => [...acc2, ...model.options.map((i) => ({ [model.name]: i.label }))]
, acc
),
[]
);
console.log(result);
Not sure where RxJs comes into this question but if you are looking to transform an object like this that comes back from a http request you would pipe it into the map operator and then use this function inside the map. If you are looking to do a reduce on a stream there is a reduce operator that emits the accumulator when the source stream completes or the scan operator that emits the accumulator each time the source emits.
Use nested calls to flatMap(), and in the innermost call you concatenate the model name with the option label.
const data = [{
"models": [{
"name": "xyz",
"options": [{
"label": "blue"
},
{
"label": "brown"
},
]
},
{
"name": "abc",
"options": [{
"label": "yellow"
}]
},
{
"name": "def",
"options": [{
"label": "green"
}]
}
]
}];
let result = data.flatMap(d => d.models.flatMap(model => model.options.map(option => `${model.name}: ${option.label}`)));
console.log(result);
Here is using multiple forEach and destructuring
const flat = (arr, res = []) => {
arr.forEach(({ models }) =>
models.forEach(({ name, options }) =>
options.forEach(({ label }) => res.push({ [name]: label }))
)
);
return res;
};
const data = [
{
models: [
{
name: "xyz",
options: [
{
label: "blue",
},
{
label: "brown",
},
],
},
{
name: "abc",
options: [
{
label: "yellow",
},
],
},
{
name: "def",
options: [
{
label: "green",
},
],
},
],
},
];
console.log(flat(data));
const response = array[0].models.reduce((initial, model) => {
if (model.options.length === 1)
initial.push(`${model.name}: ${model.options[0].label}`);
else {
model.options.forEach((option) =>
initial.push(`${model.name}: ${option.label}`),
);
}
return initial;
}, []);
console.log(response)
;
// there is no need if the inner option has just one object you can just access it by model.options[0].label, that why there is a check to see if it one

Facing issue with Javascript array

I am getting an array of object data from service as below:
outputs
array= [
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/1/2020},
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/2019},
{id:3,Name:EFG,Gender:Male,DOB:09/09/2010},
{id:3,Name:EFG,Gender:Female,DOB:08/07/2021}
]
I have applied group by function and mapping by using the key
let key="id";
const groupBy=(array,key)=>{
return Object.entries(array.reduce((result,currentvalue)=>{
(result[currentValues[key]]=result[currentValue[key]]||[]).push(
currentvalue
);
return result;
},{})).map(v=>({[key]:v[0],data:v[1]})));
};
I am able to get data like this
[
{
Id:1,
data:
[
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/1/2020}
]
},
{
Id:2,
data:
[
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/3019}
]
}...
]
But I need the out put some thing like this I need to group by Id but need the Name of Id something like this
[
{
Name:GHI,
data:[
{id:1,Name:GHI,Gender:Male,DOB:12/1/2020},
{id:1,Name:GHI,Gender:Female,DOB:10/01/2020}
]
},
{
Name:ABC,
data:[
{id:2,Name:ABC,Gender:Male,DOB:02/02/2020},
{id:2,Name:ABC,Gender:Female,DOB:03/04/2019}
]
},
{
Name:EFG,
data:[
{id:3,Name:EFG,Gender:Male,DOB:09/09/2010},
{id:3,Name:EFG,Gender:Male,DOB:08/07/2021}
]
}
]
Please let me know how to retrieve data in expected format to display on UI.
try with the below code.
var arr = [
{id:1,Name:"GHI",Gender:"Male",DOB:"12/1/2020"},
{id:1,Name:"GHI",Gender:"Female",DOB:"10/1/2020"},
{id:2,Name:"ABC",Gender:"Male",DOB:"02/02/2020"},
{id:2,Name:"ABC",Gender:"Female",DOB:"03/04/2019"},
{id:3,Name:"EFG",Gender:"Male",DOB:"09/09/2010"},
{id:3,Name:"EFG",Gender:"Female",DOB:"08/07/2021"}
]
let temp = {}
arr.forEach((obj) => {
temp[obj.Name] = temp[obj.Name] || [];
temp[obj.Name].push(obj);
});
let output = Object.entries(temp).map(obj => {
return {"Name": obj[0], "data": obj[1]}
});
console.log(JSON.stringify(output, null, 2));
You may go simpler and more readable:
let result = {};
for (const data of array) {
const { Name } = data;
if (!result[Name]) {
result[Name] = { Name, data: [data] };
} else {
result[Name].data.push(data);
}
}

How to add title/key to an array of multiple objects in javascript?

I have the following function, where its extracting some data from some files and return in an array
const extractTestCases = () => {
const filesArray = []
const filterTestSuite = files.filter(test => test.includes('.test.ts'))
filterTestSuite.forEach(testsuite => {
const feature = regexMatcher(testsuite, featureRegex, 1)
const testSuites = fs.readFileSync(testsuite, { encoding: "utf8" });
const testCases = regexMatcher(testSuites, TestRegex, 1)
filesArray.push({ [feature]: testCases })
})
return filesArray;
}
which gives me an output like the following
[
{
featureCustom: [ 'somethig' ]
},
{
featureInsp: [
'bla bla',
'foo foo'
]
}
]
how to make it generate an output like the following
[
{
"features": [
{
"featureCustom": [ 'somethig'
]
},
{
"featureInsp": ['bla bla','foo foo'
]
}
]
}
]
Something like?...
const extractTestCases = () => {
const filesArray = []
filesArray.push({ [feature]: testCases })
return [
{
features: filesArray
}
];
}

json conversion from nested array to object

I have json nested array as follows:
Parent: {
Child1: [
{name:'grandchild1', value:'abc', checked:true},
{name:'grandchild2', value:'pqr', checked:false}
],
Child2: [
{name:'grandchild3', value:'abcd', checked:false},
{name:'grandchild4', value:'pqrs', checked:true}
],
parent2{...........}....
};
I need to convert it into:
[
{
"filename":"Parent",
"children":[
{
"filename":"Child1",
"children":[
{
"filename":"grandchild1",
"type":"ts"
},
{
"filename":"grandchild2",
"type":"ts"
}
]
},
{
"filename":"Child2",
"children":[
{
"filename":"grandchild3",
"type":"ts"
},
{
"filename":"grandchild4",
"type":"ts"
}
]
}
]
},
{ filename:"Parent1"..........
},....
]
It is a part of angular material tree. They have sample code Link
Tried with below code:
Object.keys(obj).reduce<FileNode[]>((accumulator, key) => {
const value = obj[key];
const node = new FileNode();
node.filename = key;
if (value != null) {
if (typeof value === 'object') {
node.children = this.buildFileTree(value, level + 1);
} else {
node.type = value;
}
}
return accumulator.concat(node);
}, []);
}
But not getting what I need.
Please suggest me how can I convert into the following format so that it will accept the corresponding way?
You can use the for of and for in functions
const list = {Parent1 :{
Child1: [
{name:'grandchild1', value:'abc', checked:true},
{name:'grandchild2', value:'pqr', checked:false}
] ,
Child2: [
{name:'grandchild3', value:'abcd', checked:false},
{name:'grandchild4', value:'pqrs', checked:true}
]
}, Parent2 :{
Child1: [
{name:'grandchild1', value:'abc', checked:true},
{name:'grandchild2', value:'pqr', checked:false}
] ,
Child2: [
{name:'grandchild3', value:'abcd', checked:false},
{name:'grandchild4', value:'pqrs', checked:true}
]
}};
const res = []
for(let parent in list){
let parentTemp = {
filename : parent,
children : []
}
for(let child in list[parent]){
let childTemp = {filename : child, children : []};
for(let grandChild of list[parent][child]){
childTemp.children.push({filename : grandChild.name, type : grandChild.value, status: grandChild.checked});
}
parentTemp.children.push(childTemp);
}
res.push(parentTemp);
}
console.log(res);

Pivot data using lodash

I need to convert the the init array to final array preferably using lodash.
initArray = [
{
"date":"2017-08-15",
"data":[
{
"color":"orange",
"count":100
},
{
"color":"green",
"count":101
}
]
},
{
"date":"2017-08-14",
"data":[
{
"color":"orange",
"count":102
},
{
"color":"green",
"count":103
}
]
}
]
finalArray = [
{
"color":"orange",
"data":[
100,
102
]
},
{
"color":"green",
"data":[
101,
103
]
}
]
This way seems like the lodash calls make sense to me.
// var _ = require('lodash')
initArray = [
{
"date":"2017-08-15",
"data":[
{
"color":"orange",
"count":100
},
{
"color":"green",
"count":101
}
]
},
{
"date":"2017-08-14",
"data":[
{
"color":"orange",
"count":102
},
{
"color":"green",
"count":103
}
]
}
]
result = _(initArray)
//.map('data')
//.flatten()
.flatMap('data') // instead of .map('data').flatten()
.groupBy('color')
.map((item, key) => ({
color: key,
count: _.map(item, 'count')
}))
.value()
console.log(result)
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>
you can use reduce to flatten the original array, so that all data arrays are on same level. Then use _.transform to get a temp object mapping colors to array of their counts. and then you can push things to finalArray using forEach.
var initArray = [
{
"date":"2017-08-15",
"data":[
{
"color":"orange",
"count":100
},
{
"color":"green",
"count":101
}
]
},
{
"date":"2017-08-14",
"data":[
{
"color":"orange",
"count":102
},
{
"color":"green",
"count":103
}
]
}
];
var finalArray = [];
var temp = _.transform(initArray.reduce((a,b) => a.data.concat(b.data)),
(r, v) => (r[v.color] || (r[v.color] = [])).push(v.count), {});
_.forEach(temp, (v,k) => finalArray.push({color:k, count:v}));
console.log(finalArray);
<script src="https://cdn.jsdelivr.net/lodash/4/lodash.min.js"></script>

Categories