How to transpose array of objects in TypeScript? - html

I am having an array of objects as below:
finalList = [
[{name: john}, {name: max}, {name: rob}],
[{id: 1}, {id: 2}, {id: 3}],
[{gender: M}, {gender: F}, {gender: M}],
]
I need the array to transpose like this:
finalList = [
{name: john, id: 1, gender: M},
{name: john, id: 1, gender: M},
{name: john, id: 1, gender: M}
]
The actual array of object is in nested array. Please help me guiding to transpose the array in TypeScript.

Here's a nice functional way. It assumes each array in finalList has the same length and same keys (so no error handling).
const finalList = [
[{name: "john"}, {name: "max"}, {name: "rob"}],
[{id: 1}, {id: 2}, {id: 3}],
[{gender: "M"}, {gender: "F"}, {gender: "M"}],
];
console.log(finalList);
// this is a trick to create an array of a specific size with unique objects inside it
// the fill is necessary to iterate over the holed array (https://stackoverflow.com/q/40297442/2178159)
// fill({}) won't work since it's a single object ref that will be shared
const results = new Array(finalList.length).fill(null).map(() => ({}));
finalList.forEach(group => {
group.forEach((obj, i) => {
Object.assign(results[i], obj);
})
});
console.log(results);

Related

Google Apps Script function to denormalize json data working erratically

I have a function to denormalize json data.
Json data looks like:
-entries
- entry
- skus
What I am trying to do is to create an array of objects where entries with more than 1 SKUs should be repeated the x times, where x is the number of skus (length of the sku array); each time switching the data of the skus.
The problem is that the sku data does not switch, and the same skus are shown multiple times in the resulting array.
When I debug step by step, the array is appended fine at the beginning, however when function proceeds the correctly appended elements of the array are overwritten.
Here the function code:
let data = [
{
name: 'a',
skus: [1, 2],
},
{
name: 'b',
skus: [3, 4],
},
{ name: 'c', skus: [5] },
{ name: 'd', skus: [6, 7, 8] },
];
function flatten(data) {
let newArray = [];
for (i in data) {
const el = {};
el.name = data[i].name;
let skus = data[i].skus;
for (j in skus) {
el.sku = skus[j];
newArray.push(el);
console.log(el);
}
}
return newArray;
}
what I am trying to achieve is to return a new array which is so:
[
{ name: a,
sku: 1
},
{ name: a,
sku: 2
},
{
name: b,
sku: 3,
},
{
name: b,
sku: 4,
}... and so on ]
Thanks
You want to achieve the following conversion.
From
const data = [
{name: 'a', skus: [1, 2]},
{name: 'b', skus: [3, 4]},
{name: 'c', skus: [5]},
{name: 'd', skus: [6, 7, 8]},
];
To
[
{"name": "a", "sku": 1},
{"name": "a", "sku": 2},
{"name": "b", "sku": 3},
{"name": "b", "sku": 4},
,
,
,
]
Modification points:
I think that the reason of your issue is due to the call by reference. When the object el is put to the array with newArray.push(el), el is changed by the next loop. By this, I think that your issue occurs. In this case, it is required to copy the object and put to the array.
When above points are reflected to your script, it becomes as follows.
Modified script:
From:
newArray.push(el);
To:
newArray.push(Object.assign({}, el));
Testing:
let data = [
{name: 'a', skus: [1, 2]},
{name: 'b', skus: [3, 4]},
{name: 'c', skus: [5]},
{name: 'd', skus: [6, 7, 8]},
];
function flatten(data) {
let newArray = [];
for (i in data) {
const el = {};
el.name = data[i].name;
let skus = data[i].skus;
for (j in skus) {
el.sku = skus[j];
newArray.push(Object.assign({}, el));
// console.log(el);
}
}
return newArray;
}
console.log(flatten(data))
Other pattern:
In your case, the following script can be also used.
const data = [
{name: 'a', skus: [1, 2]},
{name: 'b', skus: [3, 4]},
{name: 'c', skus: [5]},
{name: 'd', skus: [6, 7, 8]},
];
const res = data.reduce((ar, {name, skus}) => {
skus.forEach(e => ar.push({name: name, sku: e}));
return ar;
}, []);
console.log(res);
Reference:
Object.assign()

how to do filtering from array in angular

I have this data in my tags.ts file and I'm not sure how I can do filtering using the name. I was able to do it using a normal string list but not sure how to do it for arrays. any suggestion or help, how to do that.
export const tags2: Array<Tag> = [{name: "Lam", superTag: true},
{name: "Eliz", superTag: false},
{name: "Cathy", superTag: true},
{name: "John", superTag: false},
{name: "James", superTag: false},
{name: "David", superTag: false}];
Below code is working fine for a normal string list but not for arrays
import { tags2 } from "./tags.data";
this._filteredTags = this.tags.filter((v: string) =>
v.toLowerCase().includes(filterValue.toLowerCase().trim())
);
}
}
You you have to check the name instead on toLowerCase() on object
this._filteredTags = this.tags.filter((v: string) =>
v["name"].toLowerCase().includes(filterValue.toLowerCase().trim())
);

Dropdown default selection in Angular

I have following dropdown implementation in Angular. But I want to display the Paris as a default , but it shows None even though I assign value as 1 as follows.
.html
<p-dropdown [options]="labels" [(ngModel)]="selectedCity" optionLabel="name" (onChange)="cityChanged($event.value)"></p-dropdown>
.ts
interface City{
name: string;
value: number;
}
export class CityComponent {
selectedCity: number = 1;
constructor() {
this.labels = [
{name: 'None', value: 0},
{name: 'Paris', value: 1},
{name: 'Rome', value: 2},
{name: 'London', value: 3},
{name: 'Istanbul', value: 4},
{name: 'Amsterdam', value: 5},
{name: 'Moscow', value: 6},
{name: 'Zurich', value: 7}
];
}
cityChanged(city : City)
{
this.selectedCity = city.value
}
}
This is happening because the dropdown expects the selected value to match one of your options. Since you are storing your options as objects, but your value as a number, it is unable to find a match. The simplest approach to fix this would be to store the whole object as the selectedCity, grabbing just the value once it is needed:
export class CityComponent {
selectedCity = {name: 'Paris', value: 1};
constructor() {
this.labels = [
{name: 'None', value: 0},
{name: 'Paris', value: 1},
{name: 'Rome', value: 2},
{name: 'London', value: 3},
{name: 'Istanbul', value: 4},
{name: 'Amsterdam', value: 5},
{name: 'Moscow', value: 6},
{name: 'Zurich', value: 7}
];
}
getSelectedValue(): number {
return this.selectedCity.value;
}
cityChanged(city : City) {
this.selectedCity = city;
}
}

Trouble formatting json objects with lodash _.groupBy

I'm having trouble reformatting an object in order to group by lists.
// input
{
'M': [
{name: Bob, id: 1},
{name: John, id: 2},
{name: John, id: 3},
],
'F': [
{name: Liz, id: 4},
{name: Mary, id: 5},
{name: Mary, id: 6},
]
}
// desired output
{
'M': [
'Bob': [ {name: Bob, id: 1},]
'John': [ {name: John, id: 2}, {name: John, id: 3} ]
],
'F': [
'Liz': [ {name: Liz, id: 4} ]
'Mary': [ {name: Mary, id: 5}, {name: Mary, id: 6} ]
]
}
My current script is only returning the 'M' key and I'm not what is causing it
for (var key in obj) {
var data = _.groupBy(obj[key], 'name')
return data;
}
I've also tried
Object.keys(obj).forEach(obj, key => {
var data = _.groupBy(obj[key], 'name')
return data;
})
but it throws TypeError: #<Object> is not a function
You can use mapValues to group each gender groups by their names through groupBy.
var output = _.mapValues(input, names => _.groupBy(names, 'name'));
var input = {
'M': [
{name: 'Bob', id: 1},
{name: 'John', id: 2},
{name: 'John', id: 3},
],
'F': [
{name: 'Liz', id: 4},
{name: 'Mary', id: 5},
{name: 'Mary', id: 6},
]
};
var output = _.mapValues(input, names => _.groupBy(names, 'name'));
console.log(output);
body > div { min-height: 100%; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.js"></script>
Use _.forOwn since you want to iterate its own properties.
_.forOwn(obj, function(key, val) {
var ret = {};
ret[key] = _.groupBy(val, 'name');
return ret;
});

dynamic create json for treeview

I want to turn json
var treeNodes = [ {managerid:root,Employeeid:01},
{managerid:01,Employeeid:11},
{managerid:01,Employeeid:22},
{managerid:22,Employeeid:33},
{managerid:22,Employeeid:44}
];
into json like this using javascript.
json={
id:root,
children[{
id:01,
children[
{id:11},
{id:22}
]
children[
{id:33},
{id:44}
]
}
Can someone help with java script function?
First of all, your current JSON is incorrect:
var json = {
id: root,
children: [
{
id: 01,
children: [
{id: 11},
{id: 22}
]
},
{
children: [
{id: 33},
{id: 44}
]
}
]
};
Second, could you give more information about your table Employee?