How to join object values into an array? - javascript

The current data that I have:
const data = [{ persons: [{name: "a", id: 1}], type: 1},
{ persons: [{name: "b", id: 1}], type: 2},
{ persons: [{name: "c", id: 1}], type: 3},
{ persons: [{name: "d", id: 1}], type: 4}]
What I want to achieve is:
const result = { people: [{names: ["a","b","c","d"], id: 1}], types: [1,2,3,4]}
What I have tried to do:
const result = data.reduce((result, {persons, type}) => {
for(let i = 0; i < persons.length; i++) {
if (!result.people[i]) {
result.people.push({names: [persons[i].name], id: persons[i].id]});
continue;
}
result.people[i].names.push(persons[i].name);
}
result.types.push(type);
return result
}, {people: [], types: []})
Is there perhaps a better, more elegant way to approach this?

You may use { people: {}, type: {} } in the reduce() to create a hashmap to reduce the loop.
Also, you can extract the data later with Object.vaues()
const data = [
{ persons: [{ name: "a", id: 1 }], type: 1 },
{ persons: [{ name: "b", id: 1 }], type: 2 },
{ persons: [{ name: "c", id: 1 }], type: 3 },
{ persons: [{ name: "d", id: 1 }], type: 4 },
{ persons: [{ name: "d", id: 1 }], type: 4 },
{ persons: [{ name: "d", id: 1 }], type: 4 },
{
persons: [
{ name: "d", id: 1 },
{ name: "k", id: 2 },
],
type: 4,
},
];
const groupByData = data.reduce(
(acc, cur) => {
for (const person of cur.persons) {
if (acc.people[person.id]) {
acc.people[person.id].names.push(person.name);
} else {
acc.people[person.id] = { names: [person.name], id: person.id };
}
}
if (!acc.type[cur.type]) {
acc.type[cur.type] = cur.type;
}
return acc;
},
{ people: {}, type: {} }
);
const output = {
people: Object.values(groupByData.people),
types: Object.values(groupByData.type),
};
console.log(output);

Try this:
const data = [{ persons: [{name: "a", id: 1}], type: 1},
{ persons: [{name: "b", id: 1}], type: 2},
{ persons: [{name: "c", id: 1}], type: 3},
{ persons: [{name: "d", id: 1}], type: 4}]
const people = []
const types = []
const id = data[0].persons[0].id
const result = data.reduce( (a, p) => {
people.push(p.persons[0].name)
types.push(p.type)
return{
people:[{names:people , id}] , types
}
} , data[0])
console.log(result)

Related

Convert nested aray into group of objects: Javacript

I am having an object that has the following structure
const arr = [
{field: "f1", values: [{ count:1, value: "a"}, { count:2, value: "b"}] },
{field: "f2", values: [{ count:3, value: "c"}, { count:4, value: "d"}] }
];
Output should look like
output = {
f1: { name: "f1", selected: [] },
f2: { name: "f2", selected: [] }
}
Basically the value in field should be key in the new object, also its name should have the same value with empty selected array
Code that I tried.
arr.map(item => {
return { item: { name: item, selected: [] } }
}
);
const arr = [
{ field: "f1", values: [{ count: 1, value: "a" }, { count: 2, value: "b" }] },
{ field: "f2", values: [{ count: 3, value: "c" }, { count: 4, value: "d" }] }
]
const output = arr.reduce((p, { field }) => {
p[field] = { name: field, selected: [] };
return p;
}, {});
console.log(output);
We can use Array.reduce() to do it
let arr = [
{ field: "f1", values: [{ count: 1, value: "a" }, { count: 2, value: "b" }] },
{ field: "f2", values: [{ count: 3, value: "c" }, { count: 4, value: "d" }] }
]
let result = arr.reduce((a,v) => {
let obj = {'name':v.field, 'selected': []}
a[v.field] = obj
return a
},{})
console.log(result)
Reduce saves an assignment but makes the code more complex to read.
forEach is better in this case
const obj = {};
arr.forEach(({field}) => obj[field] = {name:field, selected:[]})
console.log(obj)
<script>
const arr = [
{field: "f1", values: [{ count:1, value: "a"}, { count:2, value: "b"}]},
{field: "f2", values: [{ count:3, value: "c"}, { count:4, value: "d"}]}
];
</script>
Alternative is creating an object from entries generated from a map.
Still shorter than a reduce, but getting closer to it.
Still easier to see we end up with an object than go looking for the reduce initialiser.
const obj = Object.fromEntries(
arr.map(({field}) => [field, {name:field, selected:[]}])
);
console.log(obj);
<script>
const arr = [
{field: "f1", values: [{ count:1, value: "a"}, { count:2, value: "b"}]},
{field: "f2", values: [{ count:3, value: "c"}, { count:4, value: "d"}]}
];
</script>
You can use a .map() to get the field name, and a .reduce() to compose the object from the field name:
const input = [
{field: "f1", values: [{ count:1, value: "a"}, { count:2, value: "b"}] },
{field: "f2", values: [{ count:3, value: "c"}, { count:4, value: "d"}] }
];
let result = input.map(obj => obj.field).reduce((acc, name) => {
acc[name] = { name: name, selected: [] };
return acc;
}, {});
console.log(result);

search an item in multidimentionnal array

I'm trying to find an element on a multidimentionnal array usin JAVASCRIPT function, but I get error
This is my array's data:
export const datas = [
{
id: 1,
firstName: 'John',
tables: [
{ ID: 11, title: 'Lorem' },
{ ID: 12, title: 'Ipsum' },
],
},
{
id: 2,
firstName: 'Doe',
tables: [
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
{ ID: 23, title: 'Korem' },
],
},
{
id: 3,
firstName: 'Brad',
tables: [
{
ID: 30,
title: 'Mern',
nodes: [{ name: 'Name4' }, { name: 'Name5' }, { name: 'Name6' }],
},
{
ID: 31,
title: 'Full',
nodes: [{ name: 'Name7' }, { name: 'Name8' }, { name: 'Name9' }],
},
],
},
];
I've tried a reccursive function but it's not work, this is my code :
export const findById = (arr, id) => {
for (let o of arr) {
if (o.tables.length > 0) {
let a = findById(o.tables.nodes, 'id');
console.log(a);
}
}
};
I want to print the Object with ID 22, the problem is that I don't have the same structure in each dimension, and it still confuse me..
My Input : 22
My output :
{
ID: 22,
title: 'Arke',
nodes: [{ name: 'Name1' }, { name: 'Name2' }, { name: 'Name3' }],
},
Have you an idea how to edit my function to get my input's response ?
Your recursive function wasn't too far off, you need to check if the item as a tables first before recursively calling it again. And then finally just check the ID in the loop.
eg..
const datas=[{id:1,firstName:"John",tables:[{ID:11,title:"Lorem"},{ID:12,title:"Ipsum"}]},{id:2,firstName:"Doe",tables:[{ID:22,title:"Arke",nodes:[{name:"Name1"},{name:"Name2"},{name:"Name3"}]},{ID:23,title:"Korem"}]},{id:3,firstName:"Brad",tables:[{ID:30,title:"Mern",nodes:[{name:"Name4"},{name:"Name5"},{name:"Name6"}]},{ID:31,title:"Full",nodes:[{name:"Name7"},{name:"Name8"},{name:"Name9"}]}]}];
function findById(arr, ID) {
for (const a of arr) {
if (a.tables) {
const r = findById(a.tables, ID);
if (r) return r;
}
if (a.ID === ID) return a;
}
}
console.log(findById(datas, 22));
if you just need the nested data you can use flatMap and find
const findById = (arr, id) =>
arr
.flatMap(d => d.tables)
.find(t => t.ID === id)
const datas = [{
id: 1,
firstName: 'John',
tables: [{
ID: 11,
title: 'Lorem'
},
{
ID: 12,
title: 'Ipsum'
},
],
},
{
id: 2,
firstName: 'Doe',
tables: [{
ID: 22,
title: 'Arke',
nodes: [{
name: 'Name1'
}, {
name: 'Name2'
}, {
name: 'Name3'
}],
},
{
ID: 23,
title: 'Korem'
},
],
},
{
id: 3,
firstName: 'Brad',
tables: [{
ID: 30,
title: 'Mern',
nodes: [{
name: 'Name4'
}, {
name: 'Name5'
}, {
name: 'Name6'
}],
},
{
ID: 31,
title: 'Full',
nodes: [{
name: 'Name7'
}, {
name: 'Name8'
}, {
name: 'Name9'
}],
},
],
},
];
console.log(findById(datas, 22))
js has amazing array options https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array
the ones which will help you most are probably:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap
here are some examples
// get the base with id 22
const baseWith22ID = datas.filter(f => f.tables.filter(s => s.id = 22))
// (i guess you want this one) get all elements with id 22
const onlyElementsWith22ID = datas.flatMap(f => f.tables.filter(s => s.id = 22))

Array to Array group convert

I need to convert this array in JavaScript. I have tried many ways but not working...
value = [
{
group: "Switzerland",
id: "A",
name: "ABC"
},
{
group: "Switzerland",
id: "B",
name: "ABC3"
},
{
group: "France",
id: "C",
name: "ABC1"
},
{
group: "Italy",
id: "F",
name: "ABC3"
}
]
I need to convert the above array to the below array format.
value = [
{
name: 'Switzerland',
bank: [
{
group: "Switzerland",
id: "A",
name: "ABC"
},
{
group: "Switzerland",
id: "B",
name: "ABC3"
}
]
},
{
name: 'France',
bank: [
{
group: "France",
id: "C",
name: "ABC1"
}
]
},
{
name: 'Italy',
bank: [
{
group: "Italy",
id: "F",
name: "ABC3"
}
]
}
]
You can just iterate through the original objects and copy the values into a new object that corresponds to your new model.
let newArray = []
for (let item of value) {
let newItem = {
name: item.group,
bank: [{
group: item.group,
id: item.id,
name: item.name,
}]
}
newArray.push(newItem)
}
(You should always include some explanation about what you were trying to achieve and what is the starting point of your code, but hope this helps.)
Go through the items, and build an object with key as group.
when same group item occur, aggregate the values.
const combine = (arr) => {
const all = {};
arr.forEach((item) => {
if (!all[item.group]) {
all[item.group] = {
name: item.group,
bank: [],
};
}
all[item.group].bank.push({ ...item });
});
return Object.values(all);
};
value = [
{
group: "Switzerland",
id: "A",
name: "ABC",
},
{
group: "Switzerland",
id: "B",
name: "ABC3",
},
{
group: "France",
id: "C",
name: "ABC1",
},
{
group: "Italy",
id: "F",
name: "ABC3",
},
];
console.log(combine(value));
According to your sample
function format(data) {
const arr = [];
const temp = {};
data.forEach((obj, index) => {
const item = { name: obj.group, bank: [] };
if (temp.hasOwnProperty(obj.group)) {
arr[temp[obj.group]].bank.push(obj);
} else {
item.bank.push(obj);
arr.push(item);
}
temp[obj.group] = index;
});
return arr;
}
console.log(format(value));
https://stackblitz.com/edit/js-etadh9

How to Structure This array, Separate Category and Product

I have single array, I want to separate category and category Product
const product = [{
id: 1,
name: 'Cloth',
cat: ['fashion', 'man', 'women']
}, {
id: 2,
name: 'Shoes',
cat: ['fashion']
}, {
id: 3,
name: "hat",
cat: ['man', 'fashion']
}]
How to Separate category value from Product array.
const cat = ['fashion','man','women']
How to Separate category and Product
const result = [{
cat: 'fashion',
[{
id: 1,
name: 'Cloth'
}, {
id: 2,
name: 'Shoes'
}, {
id: 3,
name: "hat"
}]
}, {
cat: 'man',
[{
id: 1,
name: 'Cloth'
}, {
d: 3,
name: "hat"
}]
}, {
cat: 'women',
[{
id: 1,
name: 'Cloth'
}]
}]
How to develop this type of array please help me. Any one know please help me, Advance tanks for reply
First answer:
let categories = [];
const product = [
{ id: 1, name: "Cloth", cat: ["fashion", "man", "women"] },
{ id: 2, name: "Shoes", cat: ["fashion"] },
{ id: 3, name: "hat", cat: ["man", "fashion"] }
];
product.forEach((p) => {
p.cat.forEach((cat) => {
if(!categories.includes(cat)) {
categories.push(cat)
}
})
})
console.log(categories) // ['fashion','man','women']
If you one to get All categories from product Array.
let allCategories = [];
product.forEach(p => {
allCategories.push(...p.cat);
});
allCategories = [...new Set(allCategories)];
For second question I will use the result of first question:
allCategories.forEach(categorie => {
result.push(
{
cat: categorie,
products : product.filter(p => {
if(p.cat.includes(categorie)) {
return {
id : p.id,
name : p.name
}
}
})
}
)
})

How to fetch data from complex array objects structures?

I have such an object
data: {
dataFirst: {
Food: [ {id: 536131, name: "option1", }]
},
dataSecond: {
Autos: [{id: 678, name: 'option1'}],
Houses: [
{id: 6876, name: "option1"},
{id: 6876, name: "Placed App"},
],
Phones: [
{id: 672, name: "option1"},
{id: 97249, name: "Placed},
],
Food: [
{id: 772, name: "option1"},
{id: 6777, name: "Placed},
],
}
}
The problem is, that I may have same data in dataFirst and dataSecond, for examle 'Food', I have 2 array objects that contains different data but I need to make it one object 'Food' with the data from 2 of them, from the dataFirst 'Food' and dataSecond 'Food'. I had such a code:
export const parser = ({ data }) => {
const result = Object.values(data).reduce((prev, topicsGroup) => {
Object.assign(prev, topicsGroup);
return prev;
}, {});
return result;
}
but this code doesn't unite 2 'Food' objects but returns data only from the dataFirst 'Food' object wihout second one.
You can iterate through all values of your main data object with Object.values(data) and combine them with reduce by concatenating arrays corresponding to common keys:
let data = {
dataFirst: {
Food: [{
id: 536131,
name: "option1",
}]
},
dataSecond: {
Autos: [{
topicId: 678,
name: 'option1'
}],
Houses: [{
topicId: 6876,
name: "option1"
},
{
topicId: 6876,
topicName: "Placed App"
},
],
Phones: [{
topicId: 672,
name: "option1"
},
{
topicId: 97249,
name: "Placed"
},
],
Food: [{
topicId: 772,
name: "option1"
},
{
topicId: 6777,
name: "Placed"
},
],
}
};
let res = Object.values(data).reduce((acc, curr) => {
Object.entries(curr).forEach(([k, v]) => {
if (k in acc) acc[k] = acc[k].concat(v);
else acc[k] = v;
});
return acc;
}, {});
console.log(res);

Categories

Resources