I am trying to convert Array of Arrays that I get from Observable into single array of objects. This is my code:
this.jobsService.jobsUpdated.pipe(
map(
(jobsData)=> {
return jobsData.map(
(job)=>{
return job.parts.map((part)=>{ return part })
}
)
}
)
).subscribe(
(partsData)=>{
console.log('partsdata', partsData)
}
);
This is the data format I am getting back:
[
[
{partName:1, number:10, quantity: 100}
],
[
{partName:2, number:20, quantity: 200},
{partName:3, number:30, quantity: 300}
],
etc...
]
Please help to convert this data, hopefully in the pipe method, into :
[
{partName:1, number:10, quantity: 100},
{partName:2, number:20, quantity: 200},
{partName:3, number:30, quantity: 300}
]
Use reduce and no need of using inner map
Why reduce? - To generate single output based on multiple inputs.
this.jobsService.jobsUpdated.pipe(
map((jobsData)=> {
return jobsData.reduce(
(acc, job)=>{
acc.push(...job.parts)
return acc;
}
, [])
})
);
Alternatively concat can also be used
this.jobsService.jobsUpdated.pipe(
(jobsData)=> jobsData.reduce(
(acc, job)=> acc.concat(job.parts), [])
})
);
If you just want a flat array:
this.jobsService.jobsUpdated
.pipe(
pluck('parts'),
map((parts)=> parts.flat())
)
Related
I have an array that looks like this:
const updatedUsersInfo = [
{
alias: 'ba',
userId: '0058V00000DYOqsQAH',
username: 'ba#dna05.com',
permissionSets: [
'X00e8V000000iE48QAE',
'SCBanquetAccess',
'SCViewOnlyPermission'
]
},
{
alias: 'cs',
userId: '0058V00000DYOqtQAH',
username: 'cs#dna05.com',
permissionSets: [ 'X00e8V000000iE45QAE', 'SCCorpAdmin', 'SEAdmin' ]
}
]
I need to remove from the embedded permissionSets array just the value that starts with 'X00' and looks like this after.
const updatedUsersInfo = [
{
alias: 'ba',
userId: '0058V00000DYOqsQAH',
username: 'ba#dna05.com',
permissionSets: [
'SCBanquetAccess',
'SCViewOnlyPermission'
]
},
{
alias: 'cs',
userId: '0058V00000DYOqtQAH',
username: 'cs#dna05.com',
permissionSets: [ 'SCCorpAdmin', 'SEAdmin' ]
}
]
I have tried many ways to achieve this, however, no matter which way I do it I get a variable 'undefined'
Here is some of the ways I have attempted this:
let test = updatedUsersInfo.forEach((element => element['permissionSets'].filter((permissionSet) => !permissionSet.includes('X00'))));
let test2 = updatedUsersInfo.forEach(element => {
element['permissionSets'].filter((permissionSet) => {
return !permissionSet.includes('X00')
});
});
I have also tried to splice but it also returned an error stating the array could not be spliced. I am primarily a C# developer and typescript is an entirely new ball field for me so any help would be great!
You should use map() and filter() to treat the object as immutable (i.e. a data object should not be changed after its creation).
You should not use includes("X00") as it will also match strings like beforeX00after but you only want to remove those starting with X00. Use startsWith("X00") instead.
const updatedUsersInfo = [
{
alias: "ba",
userId: "0058V00000DYOqsQAH",
username: "ba#dna05.com",
permissionSets: [
"X00e8V000000iE48QAE",
"SCBanquetAccess",
"SCViewOnlyPermission",
],
},
{
alias: "cs",
userId: "0058V00000DYOqtQAH",
username: "cs#dna05.com",
permissionSets: ["X00e8V000000iE45QAE", "SCCorpAdmin", "SEAdmin"],
},
];
const updated = updatedUsersInfo.map((info) => ({
...info,
permissionSets: info.permissionSets.filter((p) => !p.startsWith("X00")),
}));
console.log(JSON.stringify(updated, null, 4))
/* StackOverflow snippet: console should overlap rendered HTML area */
.as-console-wrapper { max-height: 100% !important; top: 0; }
This implementation uses the spread syntax introduced with ES6 as well as rest properties to create new objects from existing object while updating a property.
So I'm using mongodb to fetch some data from the database.
The issue is when I try to check for something in an array
Here is what the structure looks like:
Example array structure
{ // ...
likedPeople: [
{
name: "foo"
image: "test",
},
{
name: "bar",
image: "baz",
}
]
}
This is the array i get Back.
So when i try to find if it includes a certain value,
eg:
const displayName = "foo";
console.log(
likedPeople.map((likedPerson) => {
return likedPerson.name === displayName; // Output: [true, false]
})
);
But then If i again try to do some other method on it like map() or includes(), It breaks the setup:
const response = likedPerson.name === displayName; // Output: [true, false]
response.map((res) => console.log(res)); // Output: ERROR: response.map() is not a function
But the fact is that I am getting an array with the values, so what am I even doing wrong here?
I tried adding an optional chaining response?.map() but still it gave me the same error.
Also the includes() method also returns me the same response.includes is not a function error.
Can anyone help?
Use the some method to check the name exists in likedPeople :
const likedPeople = [
{
name: "foo",
image: "test",
},
{
name: "bar",
image: "baz",
}
];
const displayName = "foo";
const isExist = likedPeople.some(people => people.name === displayName);
console.log(isExist)
how to convert an object into an array of objects following the example below
const obj = { "banks": 66.22, "desk": 40.40, "manager": 80.03, "totalBanks": 213", "totalDesk": 413", "totalManager": 113" }
the objective is that this object from above, is in this format below
const arra =[{title: "banks", quantity: 66.22, totalBanks: 212}, {title: "desk", quantity: 400, totalDesk: 413}, {title: "manager", quantity: 80.03, totalManager: 113}]
I am using this approach below with no expected success
Object.entries(obj).map(([key, value]) => ({key, value })).map(val => ({
title: val,
quantity: percent(val),
total: total(val),
})
function percent(val){
if(val.key === "banks") {
return val.value
}
}
function total(val){
if(val.key === "totalBanks") {
return val.value
}
}
I want to find a value inside an array that is already inside an array.
To give an example of my array:
[
{
ConcessionId: 1,
ConcessionName: "Coyotes",
KnownAs: [
{
TeamId: 1,
Name: "Arizona Coyotes",
},
{
TeamId: 2,
Name: "Phoenix Coyotes",
}
]
},
{
ConcessionId: 2,
ConcessionName: "Devils",
KnownAs: [
{
TeamId: 3,
Name: "Colorado Rockies",
},
{
TeamId: 4,
Name: "New-Jersey Devils",
}
]
}
]
What I want is when Icall my function it returns me the team name.
For example, I the parameter value is 3, I want Colorado Rockies as a name:
public getInfo(_TeamID) {
const concession: ConcessionInfo[] = this.concessionList$.filter(function (x) {
x.KnownAs.filter( (y)=> {
y.TeamId= +_TeamID;
return y.Name;
})
})
}
I try so many different way with filter. But never get something good. Never works.
I can make a double .foreach , for each array. but I think a better method exist than making a double loop.
Thanks
Instead of using the filter method (which is in fact working similar as a for loop), you could do forEach on both arrays. For your current data structure, there is no other way around it.
getInfo = (_TeamID) => {
let teamName = '';
this.concessionList$.forEach(entry => {
entry.KnownAs.forEach(team => {
if(team.TeamId === _TeamID){
teamName = team.Name;
return; // break the loop.
}
})
});
return teamName;
}
Here is a working example
https://stackblitz.com/edit/double-for-lopp
EDIT
If you have a look at the polyfill implementation of filter from Mozilla https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter which is in equivalent to the native implementation of filter, you can see that it is looping through the whole array, the same way as a forEach loop. The difference is that the filter method will return a new array based on the boolean condition inside the callback function, while a forEach loop does not return anything.
Assuming myArray is contains the data you provided.
The following code will work if you're using Typescript 3.7 and above.
public getInfo(teamId: number): string | undefined {
const team = this.concessionList$
.map(concession => concession.KnownAs)
.reduce((a, b) => a.concat(b), [])
.find(team => team.TeamId === teamId)
return team ? team.Name : undefined
}
Usage:
this.getInfo(3) // Colorado Rockies
Ok how this work?
You have to understand what is find. For example:
const result = [{name: 'foo', age: 1}, {name: 'bar', age: 2}]
.find(people => people.name === 'foo')
console.log(result) // {name: 'foo', age: 1}
I have an object
{
key1:'val1',
key2:'val2',
key3:'val3',
key4:'val4'
}
I need to convert it to the following:
[
{key:'val1'},
{key:'val2'},
{key:'val3'},
{key:'val4'}
]
The key in the final object is fixed.
How do i do this using lodash or underscore? I know I can use _.values and then forEach on it, but somehow that doesn't feel right.
No need for lodash or underscore. Just map over the Object.keys()
var obj = {
key1:'val1',
key2:'val2',
key3:'val3',
key4:'val4'
};
var newObj = Object.keys(obj).map(function (k) {
return {
key: obj[k]
}
});
console.log(newObj);
Below is a lodash version
_.map({
key1: 'val1',
key2: 'val2',
key3: 'val3',
key4: 'val4'
}, function( value ) { return { key: value }; } );