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
Related
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)
I have an array which I'm trying to filter based on a certain nested value, without getting any other elements.
const arrayData = [
{
country: "Country X",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Saly', status:'Blocked' }]
},
]
},
{
country: "Country Y",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }]
},
]
},
];
What I have tried:
let output = arrayData.filter(eachVal => {
let opt = eachVal.games.some((
{ players }) => players
.some(({ status}) => status === 'Active'));
return opt;
})
Expected result for finding all players with value status : 'Active':
{
country: "Country X",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'John', status:'Active' }]
}
]
}
But the result:
[{"country":"Country X","games":[{"gameTitle":"Game1","players":[{"name":"John","status":"Active"},{"name":"Rob","status":"Suspended"}]},{"gameTitle":"Game2","players":[{"name":"Saly","status":"Blocked"}]}]}]
Try this:
arrayData.map(({country, games: g}) => {
const games = g.map((g) => {
const players = g.players.filter((p) => p.status === 'Active')
return {...g, players}
})
.filter(({players}) => players.length > 0)
return {country, games}
}).filter(({games}) => games.length>0)
The logic is nested filter through each level and assigning the finds back to their respective places and using forEach logic to see if an object has an "Active" value
const arrayData = [
{
country: "Country X",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Saly', status:'Blocked' }]
},
]
},
{
country: "Country Y",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }]
},
]
},
];
//answer
let arr=JSON.parse(JSON.stringify(arrayData))
arr=arr.filter(a=>{
let f=a.games; let i=false
f=f.filter(b=>{
let x=b.players; let j=false
x=x.filter(c=>c.status=="Active")
x.forEach(c=>{if(c.status=="Active"){j=true}})
b.players=x; return j
})
f.forEach(b=>{
b.players.forEach(c=>{if(c.status=="Active"){i=true}})
})
a.games=f; return i
})
console.log(arr)
It's quite easy. You just need some map and filter:
const arrayData = [
{
country: "Country X",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'John', status:'Active' },{ name: 'Rob', status:'Suspended' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Saly', status:'Blocked' }]
},
]
},
{
country: "Country Y",
games: [
{
gameTitle: 'Game1',
players: [{ name: 'Sindy', status:'Pending' },{ name: 'someone', status:'Rejected' }]
},
{
gameTitle: 'Game2',
players: [{ name: 'Alex', status:'New' },{ name: 'Nic', status:'Old' }]
},
]
},
];
/*------------------------------- This is the answer -------------------------------*/
let result = arrayData.map(a => ({...a, games: a.games.map(g => ({...g, players: g.players.filter(p => p.status === 'Active')})).filter(g => g.players.length)})).filter(a => a.games.length)
/*----------------------------------------------------------------------------------*/
console.log(result)
I'd "recursively" select the valid elements at each level and map on each filtered array to build the correct output:
const selectActivePlayers = (players) => players.filter(player => player.status === "Active");
const selectValidGames = (games) => games.filter(game => selectActivePlayers(game.players).length > 0)
const selectValidCountries = (countries) => countries.filter(country => selectValidGames(country.games).length > 0);
const cleanCountries = selectValidCountries(arrayData).map(country => ({
...country,
games: selectValidGames(country.games).map(game => ({
...game,
players: selectActivePlayers(game.players)
}))
}))
Output:
[
{
"country": "Country X",
"games": [
{
"gameTitle": "Game1",
"players": [
{
"name": "John",
"status": "Active"
}
]
}
]
}
]
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
}
}
})
}
)
})
I have an object with arrays of objects. I'm trying to loop through these arrays with _.forEach() and then group each array with _.groupBy(). But the function is just returning the original data.
const testData = {
"1": [
{ name: "john", job: "programmer" },
{ name: "jean", job: "dentist" },
{ name: "jo", job: "programmer" },
{ name: "jeff", job: "chef" },
{ name: "jock", job: "dentist" }
],
"2": [
{ name: "julie", job: "doctor" },
{ name: "billy", job: "clerk" },
{ name: "carol", job: "doctor" },
{ name: "claire", job: "clerk" },
{ name: "cedric", job: "lawyer" }
]
};
const groupedTest = data => {
return _.forEach( data, arraygroup => {
_.groupBy( arraygroup, obj => obj.job );
} );
};
const result = groupedTest(testData)
console.log( result );
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
I'm looking to return a new object with the arrays grouped by job, but this function is just returning the original data. I can't figure out where I've gone wrong with the logic :-( Thanks very much for any help you can give me..
_.forEach returns the original collection - use _.map and make sure you're returning everything.
const testData = {"1":[{name:"john",job:"programmer"},{name:"jean",job:"dentist"},{name:"jo",job:"programmer"},{name:"jeff",job:"chef"},{name:"jock",job:"dentist"}],"2":[{name:"julie",job:"doctor"},{name:"billy",job:"clerk"},{name:"carol",job:"doctor"},{name:"claire",job:"clerk"},{name:"cedric",job:"lawyer"}]};
const groupedTest = data => _.map(data, arraygroup => _.groupBy(arraygroup, obj => obj.job));
const result = groupedTest(testData)
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: auto; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
With lodash you could do _.values followed by _.map and then inside go with _.groupBy in order to get the grouping by job:
const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };
let result = _.map(_.values(data), arr => _.groupBy(arr, 'job'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
If you actually want to preserve the keys in the initial object then simply use _.mapValues with _.groupBy:
const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };
let result = _.mapValues(data, arr => _.groupBy(arr, 'job'))
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
Very similar and without the need of lodash you can do with ES6:
const data = { "1": [ { name: "john", job: "programmer" }, { name: "jean", job: "dentist" }, { name: "jo", job: "programmer" }, { name: "jeff", job: "chef" }, { name: "jock", job: "dentist" } ], "2": [ { name: "julie", job: "doctor" }, { name: "billy", job: "clerk" }, { name: "carol", job: "doctor" }, { name: "claire", job: "clerk" }, { name: "cedric", job: "lawyer" } ] };
let result = Object.values(data).map(x => x.reduce((r, {name, job}) => {
r[job] = [...(r[job] || []), {name, job}]
return r
}, {}))
console.log(result)
Difference is that we achieve the group by via Array.reduce
Another option would be to consider the use of built in functions Object.entries() and Array.reduce() to achieve what you require:
const testData = {
"1": [
{ name: "john", job: "programmer" },
{ name: "jean", job: "dentist" },
{ name: "jo", job: "programmer" },
{ name: "jeff", job: "chef" },
{ name: "jock", job: "dentist" }
],
"2": [
{ name: "julie", job: "doctor" },
{ name: "billy", job: "clerk" },
{ name: "carol", job: "doctor" },
{ name: "claire", job: "clerk" },
{ name: "cedric", job: "lawyer" }
]
};
/*
Iterate key/value pairs of testData and reduce these to a new results object
where values are nested grouping object
*/
const results = Object.entries(testData).reduce((output, [key,array]) => {
/*
Reduce array value to a group, where the grouping is based on the job key
*/
const group = array.reduce((result, item) => {
if( Array.isArray( result[ item.job ] )) {
/*
If item.job key present in result (corresponding group) then add item
to the key's group value
*/
result[ item.job ].push(item);
}
else {
/*
Otherwise, start a new group array for this yet unseen item.job key
*/
result[ item.job ] = [ item ];
}
return result;
}, {});
output[ key ] = group;
return output;
}, {});
console.log(results)
The advantage of this approach is that it is independent of the loadash library
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);