Flatten an object of child arrays - javascript

I have Object which look like
list:{
dynamicPerson: [
0: {
name:"Andrew",
company:"xCompany"
},
1: {
name:"Joseph",
company:"zCompany"
}
]
dynamicPerson2: [
0: {
name:"Andrew",
company:"xCompany"
},
1: {
name:"Joseph",
company:"zCompany"
}
]
}
I want it like
List:[
0: {
name:"Andrew",
company:"xCompany"
},
1: {
name:"Joseph",
company:"zCompany"
},
2: {
name:"Andrew",
company:"xCompany"
},
3: {
name:"Joseph",
company:"zCompany"
}
]
Note DynamicPerson is run time generated key.

You can iterate trought the keys of the object. Map the arrays to an array of array and then flatten it.
let flattened = Object.keys(list).map(key => list[key]).flat();
I modified your input slightly, because it was not syntactically right.
let list = {
dynamicPerson: [
{
name: "Andrew",
company: "xCompany"
},
{
name: "Joseph",
company: "zCompany"
}
],
dynamicPerson2: [
{
name: "Andrew",
company: "xCompany"
},
{
name: "Joseph",
company: "zCompany"
}
]
};
let flattened = Object.keys(list)
.map(key => list[key])
.flat();
console.log(flattened);

You'll find it yourself by looking for: convert object to array-of-key-value-pairs
But maybe look at the snipped in here: how-to-convert-an-object-to-an-array-of-key-value-pairs can help you

You can use flatMap():
Object.values(list).flatMap(s => s);
An example:
let list ={
dynamicPerson: [
{
name:"Andrew",
company:"xCompany"
},
{
name:"Joseph",
company:"zCompany"
}
]
, dynamicPerson2: [
{
name:"Andrew",
company:"xCompany"
},
{
name:"Joseph",
company:"zCompany"
}
]
}
const result = Object.values(list).flatMap(s => s);
console.log(result);

You can also use Object.values() and flat:
let list = {
dynamicPerson: [{
name: "Andrew",
company: "xCompany"
},
{
name: "Joseph",
company: "zCompany"
}
],
dynamicPerson2: [{
name: "Andrew",
company: "xCompany"
},
{
name: "Joseph",
company: "zCompany"
}
]
}
let List = Object.values(list).flat();
console.log(List);

Related

JavaScript Array Filtering in Nested Arrays

I have an array that looks something like this:
const arrayObj = [
{
id: 1,
itemsList: [
{
name: "Paul",
},
{
name: "Newman",
},
],
},
{
id: 2,
itemsList: [
{
name: "Jack",
},
{
name: "Man",
},
],
},
]
What I want is to filter the objects whose itemsList contain an object with the name of a certain value. For example, I want to be able to filter out an array with objects whose inner objects with names that contain "ul" (in this case the name Paul contains "ul"), it should give me an output as such:
const outputArray = [
{
id: 1,
itemsList: [
{
name: "Paul",
},
{
name: "Newman",
},
]
}
]
So far, I've only been able to filter out a simple flat array of objects with this function:
function filterByName(array: any, string: any) {
return array.filter((obj: any) =>
["name"].some((key: any) =>
String(obj[key]).toLowerCase().includes(string.toLowerCase())
)
);
}
but I don't know how to apply it to my case.
Here you can use the some method combined with the includes method
const arrayObj = [{
id: 1,
itemsList: [{
name: "Paul",
},
{
name: "Newman",
},
],
},
{
id: 2,
itemsList: [{
name: "Jack",
},
{
name: "Man",
},
],
},
]
const getFilterArray = (name) => {
return arrayObj.filter(obj => obj.itemsList.some(x => x.name.toLowerCase().includes(name.toLowerCase())))
}
console.log(getFilterArray("ul"))
const result = arrayObj.filter(({ itemsList }) =>
itemsList.some(({ name }) => name.toLowerCase().includes('ul')));
Can you try this?

Lodash how to group array of objects by array of values?

I want to group an array of objects based on a property which has an array of values,and i want to return a group for each individual value,not only for the whole array.
For example :
let crew = [
{
name:"john",
job :["electrician","carpenter"]
},
{
name: "bill",
job: ["electrician"]
},
{
name: "mark",
job: [ "carpenter"]
}
]
let groupedCrew = _.groupBy(crew,"job")
console.log(groupedCrew)
/*
carpenter:
[
{
job:
[
carpenter
],
name:
"mark"
}
],
electrician:
[
{
job:
[
"electrician"
],
name:
"bill"
}
],
electrician, carpenter:
[
{
job:
[
"electrician",
"carpenter"
],
name:
"john"
}
]
}
*/
In this example i want "john" to also appear in "electrician" group.
Any ideas ?
Once again let's group something using reduce
Here's the basic structure (plus the solution)
let crew = [{
name: "john",
job: ["electrician", "carpenter"]
},
{
name: "bill",
job: ["electrician"]
},
{
name: "mark",
job: ["carpenter"]
}
];
var obj = crew.reduce(function(agg, item) {
// grouping logic below this line
item.job.forEach(function(job) {
agg[job] = agg[job] || []
// agg[job].push (item);
// lets push only name so we can see output
agg[job].push(item.name)
})
// grouping logic above this line
return agg
}, {})
console.log(obj)
use custom .reduce() function
there is no need for lodash
const crew = [
{
name: 'john',
job: ['electrician', 'carpenter'],
},
{
name: 'bill',
job: ['electrician'],
},
{
name: 'mark',
job: ['carpenter'],
},
];
const groupedCrew = crew.reduce((groupedCrew, person) => {
person.job.forEach(job => {
if (!groupedCrew[job]) groupedCrew[job] = [];
groupedCrew[job].push(person);
});
return groupedCrew;
}, {});
console.log(JSON.stringify(groupedCrew, null, 4));

How to remove underscore from loop items?

I am trying to remove all the _er and _bx from the array, how can I do it? The way I tried doesn't seem to work. I'd like to see a solution where it removes all after _, and aswell only the letter that I put in for e.g remove all _ with er after.
const nullValue = {
collection: [{
name: "test_er"
},
{
name: "test_bx"
},
{
name: "fred"
},
{
name: "test_er"
}
]
};
const newArr = []
for (let [key, item] of nullValue.collection.entries()) {
item.name.replace(/_er/g, '')
newArr.push(item)
}
console.log(newArr)
Is this what you're looking for?
const nullValue = {
collection: [
{
name: 'test_er',
},
{
name: 'test_bx',
},
{
name: 'fred',
},
{
name: 'test_er',
},
],
};
nullValue.collection = [
...nullValue.collection.map(item => ({
name: item.name.replace(/_.*$/, ''),
})),
];
console.log(nullValue);
You can also use .split('_')[0] with the map method similar to Dmitry's answer... This gives you the first string of the split array, split at the underscore...
const nullValue = {
collection: [{
name: "test_er"
},
{
name: "test_bx"
},
{
name: "fred"
},
{
name: "test_er"
}
]
};
nullValue.collection = [ ...nullValue.collection.map( names => ({ name: names.name.split('_')[0], })),]
console.log(nullValue)
If you want to keep the original array of objects...
const nullValue = {
collection: [{
name: "test_er"
},
{
name: "test_bx"
},
{
name: "fred"
},
{
name: "test_er"
}
]
};
const newArr = { collection :
[ ...nullValue.collection.map( names =>
({ name: names.name.split('_')[0], })),
]}
console.log('newArr = ', newArr)
console.log('nullValue = ', nullValue)
You were VERY close with your original code, but the mistake was that String.replace() does not operate in-place, but rather returns its result. I've modified your code and added a comment below:
const nullValue = {
collection: [{
name: "test_er"
},
{
name: "test_bx"
},
{
name: "fred"
},
{
name: "test_er"
}
]
};
const newArr = []
for (let [key, item] of nullValue.collection.entries()) {
// My change is here
newArr.push( item.name.replace(/_er/g, '') )
}
console.log(newArr)
const nullValue = {
collection: [
{
name: "test_er"
},
{
name: "test_bx"
},
{
name: "fred"
},
{
name: "test_er"
}
]
};
nullValue.collection = nullValue.collection.map(i => i.name.replace(/_.*$/, ''))
console.log(nullValue)
This is preferable to .map() since you don't need a new array. You just want to change the strings:
const nullValue = {
collection: [
{ name: "test_er" },
{ name: "test_bx" },
{ name: "fred" },
{ name: "test_er" }
]
};
nullValue.collection.forEach(i => i.name = i.name.replace(/_.*$/, ''));
console.log(nullValue.collection);

Typescript, how to transform an object to an expeced form

I want to convert or transform an object to the other object, which I want to.
inout object looks like that:
[
{0: {contact: {
1: {
name: abc,
address: street
},
2: {
name: kdf,
address: streedsd
}
}
}
}
{4: {education: {
0: {
uni: ssdabc,
address: street
},
1: {
uni: sdaskdf,
address: streedsd
}
}
}
}
]
what I expeced is:
[
{contact: [
{
name: abc,
address: street
},
{
name: kdf,
address: streedsd
}
]
}
{education: {
[ {
name: abc,
address: street
},
{
name: kdf,
address: streedsd
}
]
}
]
any solutions??? for the best, need a dynamic method, not only for contact.
this input object will be generated dynamically.
You can use Array.map() to iterate over the outer array and Object.values() to get values as array for the contact property.
const data = [{
contact: {
0: {
name: 'abc',
address: 'street'
},
1: {
name: 'kdf',
address: 'streedsd'
}
}
},
{
education: {
0: {
uni: 'ssdabc',
address: 'street'
},
1: {
uni: 'sdaskdf',
address: 'streedsd'
}
}
}
]
const convertedData = data.map(datum => {
Object.keys(datum).forEach(key => {
datum[key] = Object.values(datum[key])
})
return datum;
})
console.log('Converted Data:',convertedData)
console.log('Original Data:', data)
Important
Be aware that this method modifies the original data. If you don't want to modify the original, you can use Array.reduce() instead of Array.map()
You can use Object.values to extract the values of an object into a list.
Here is a code snippet that applies that to each item in your input:
(Various changes have been made to input and outputs in the question, some of them are invalid json but this works for a fixed version of the latest edit)
const input = [{
contact: {
0: {
name: "abc",
address: "street"
},
1: {
name: "kdf",
address: "streedsd"
}
}
}, {
education: {
0: {
uni: "ssdabc",
address: "street"
},
1: {
uni: "sdaskdf",
address: "streedsd"
}
}
}]
const output = input.map(item => Object.entries(item).map(([key, value]) => ({
[key]: Object.values(value)
})))
console.log(output)

Javascript Alphabetised Object Key Sorting

I'm wondering, I have the following data structure:
data = [
{
name: 'Alpha',
},
{
name: 'Alfa',
},
{
name: 'Bravo',
},
{
name: 'Brafo',
},
{
name: 'Charlie',
},
{
name: 'Charly',
},
...
{
name: 'Zulu',
},
{
name: 'Zulo',
},
]
I'm expecting there to be at least one, usually more, key for each letter of the alphabet. However, if there isn't a single data.name I would still like in the below data structure to have an empty domains array [].
I was wondering, how could this be manipulated into the following data structure:
data = {
a: {
domains: [
{
name: 'Alpha',
},
{
name: 'Alfa',
},
],
},
b: {
domains: [
...
]
},
...
z: {
domains: [
...
]
},
};
I have used a few methods, which involved a pre-constructed "alphbetised" key = object array, then filtered each on the first letter of the data.name value...but I was wondering if there was a standard and performant method to acheive this?
Using reduce()
const data = [{name:"Alpha"},{name:"Alfa"},{name:"Bravo"},{name:"Brafo"},{name:"Charlie"},{name:"Charly"},{name:"Zulu"},{name:"Zulo"}]
const res = data.reduce((a, v) => {
// prepare key
let key = v.name.substring(0,1).toLowerCase()
// check key in accumulator
if (!a[key]) {
// assign domain object
a[key] = {domains: []}
}
// push domain array
a[key].domains.push(v)
return a
}, {})
console.log(res)
Here is what you want:
data = [
{
name: 'Alpha',
},
{
name: 'Alfa',
},
{
name: 'Bravo',
},
{
name: 'Brafo',
},
{
name: 'Charlie',
},
{
name: 'Charly',
},
{
name: 'Zulu',
},
{
name: 'Zulo',
},
];
console.log(data.reduce((a, c) => {
const firstLetter = c.name[0].toLowerCase();
if (a[firstLetter]) {
a[firstLetter].domains.push(c);
} else {
a[firstLetter] = { domains: [c] };
}
return a;
}, {}));

Categories