I have an array of objects like this:
const arr=[
{ name:"test",
class:3
},
{ name:"test2",
class:4
},
{ name:"test3",
class:5
},]
Now I have to convert it to a map like structure as shown below:
const map={
"name":["test","test2","test3"],
"class":[3,4,5]
}
I am clueless on how to make this kind of structure.Any leads will be appreciated.
If you have an arbitrary amount of keys you can use Object.entries()
to get all the key value pairs. Then just loop over all entries and add them to the final output.
const arr=[{name:"test",class:3},{name:"test2",class:4},{name:"test3",class:5}];
const map = arr.reduce((acc, obj) => {
for(const [key, value] of Object.entries(obj)) {
if(acc[key]) {
acc[key].push(value);
}else{
acc[key] = [value];
}
}
return acc;
}, {});
console.log(map);
Have a function that accepts the array and the property you're looking for, and return a new array of data using map for each property of your new object.
const arr=[{name:"test",class:3},{name:"test2",class:4},{name:"test3",class:5}];
function getData(arr, prop) {
return arr.map(obj => obj[prop]);
}
const map = {
name: getData(arr, 'name'),
class: getData(arr, 'class')
}
console.log(map);
It should be something like that
arr.reduce((res, obj) => {
Object.entries(obj).forEach(([k,v]) => {
if(!res[k]) res[k] = []
res[k].push(v)
})
return res
},{})
Related
I have the following array of object.
[
{ claimNumber1: 'R12345', checkNumber1: '' },
{ claimNumber2: 'T1234', checkNumber2: 'abcd' },
{ claimNumber3: 'Z4567', checkNumber3: 'qwer' }
]
Using reduce, I want to convert this to below.
{
claimNumber1:'R12345',
checkNumber1:'',
claimNumber2:'T1234',
checkNumber2:'',
claimNumber3:'Z4567',
checkNumber3:'',
}
I tried below but didn't get what I expected.
.reduce((obj, item) =>{
return {...obj,item}
} ,{});
You should spread the item object, because item is an object
const arr = [
{ claimNumber1: "R12345", checkNumber1: "" },
{ claimNumber2: "T1234", checkNumber2: "abcd" },
{ claimNumber3: "Z4567", checkNumber3: "qwer" },
];
const result = arr.reduce((obj, item, i) => {
return { ...obj, ...item, [`checkNumber${i + 1}`]: "" };
}, {});
console.log(result);
Almost there. You just need to spread the item as well.
.reduce((obj, item) => {
return {
...obj,
...item,
};
}, {});
I think you should spread every item in reducer.
Here is my code.
const res = arr.reduce((prev, item) => {
return { ...prev, ...item };
}, {});
And result is
{
claimNumber1: 'R12345',
checkNumber1: '',
claimNumber2: 'T1234',
checkNumber2: 'abcd',
claimNumber3: 'Z4567',
checkNumber3: 'qwer'
}
I'm not sure of the benefit of using reduce in this situation. A simple loop would be self-documenting, and easier to read.
const data = [
{ claimNumber1: 'R12345', checkNumber1: '' },
{ claimNumber2: 'T1234', checkNumber2: 'abcd' },
{ claimNumber3: 'Z4567', checkNumber3: 'qwer' }
];
const out = {};
// For every object in the array
for (const obj of data) {
// Get an array of its keys and iterate over them
for (const key of Object.keys(obj)) {
// If it's a claim add that value to the output
// object property, otherwise set that property value
// to an empty string.
if (key.startsWith('claim')) {
out[key] = obj[key];
} else {
out[key] = '';
}
}
}
console.log(out);
Additional documentation
Object.keys
I have an array of objects which looks like
arr = [
{"className":"section", "name":"input"},
{"className":"col", "name":"dropdown"},
{"className":"section", "name":"table"}
]
Now I want to push an object {"fieldName":"new"} after every object which has "className":"section"
So my final output should look like something like this
arr = [
{"className":"section", "name":"input"},
{"fieldName":"new"},
{"className":"col","name":"dropdown"},
{"className":"section", "name":"table"},
{"fieldName":"new"}]
How do I acheive this in Javascript?
Use Array.reduce.
let arr = [{"className":"section", "name":"input"},{"className":"col", "name":"dropdown"},{"className":"section", "name":"table"}];
arr = arr.reduce((acc, item) => {
acc.push(item);
if (item.className === "section") {
acc.push({ fieldName: "new" });
}
return acc;
}, []);
console.log(arr);
try this...
arr.forEach(obj => {
if (obj.className === 'section') {
const index = arr.indexOf(obj)
arr.splice(index, 0,
{"fieldName":"new"} )
}
})
i have the dynamic data coming in this format, i want to turn into and array based on the toolset object keys, but toolset object have not constant number of keys
{ toolset:{
info1:{
event-date:{},
event-time:{},
},
info2:{
event-location:{},
event-url:{},
}
}}
i want it like this
inputs=[{event-date:{}},{event-time:{}},{event-location:{}},{event-url:{}}]
with the minimal code in javascript es6
You could use map, flat and Object.entries methods to return flat array of objects.
const data = {
toolset: {
info1: {
'event-date': {},
'event-time': {},
},
info2: {
'event-location': {},
'event-url': {},
}
},
}
const inputs = Object
.values(data.toolset)
.map(Object.entries)
.flat()
.map(([k, v]) => ({[k]: v}))
console.log(inputs)
This should work:
let obj = {
toolset: {
info1: {
"event-date": {},
"event-time": {}
},
info2: {
"event-location": {},
"event-url": {}
}
}
};
let finalArray = [];
Object.values(obj.toolset).forEach(obj => {
Object.entries(obj).forEach(([key, val]) => finalArray.push({ [key]: val }));
});
console.log(finalArray); // <== your desired array
I have an array like this
let oldArray=[
{type:16,img:['1']},
{type:16,img:['2']},
{type:16,img:['3']},
{type:17,img:['4']}
]
if the type is the same, i want to concat the value.
The result I want is:
let newArray=[
{type:16,img:['1','2','3']},
{type:17,img:['4']}
]
I tried to used reduce function:
oldArray.reduce((acc,cur,idx,src)=>{
if(cur.type===a[idx+1].type){
cur.img.concat(a[idx+1].img);
acc.push(cur)
} else {
acc.push(a[idx+1])
}
return acc
},[])
It seems that there is an error
Can anyone help? Thanks.
Alternative to Bibberty's solution:flatMap is much clearer than reduce
let newArray = [...new Set(oldArray.map(e => e.type))]
.map(e => {
return {
type: e,
img: (oldArray.filter(i => i.type === e).map(x => x.img)).reduce((acc,cur,idx,src)=>{
let length=src.length
let tep=cur.concat(src[idx+1]);
src[idx+1]=tep
return src[idx=length-1]
},[])
}
});
console.log(newArray);
You can use reduce:
let oldArray = [{type: 16,img: ['1']},{type: 16,img: ['2']},{type: 16,img: ['3']},{type: 17,img: ['4']}];
let newArray = oldArray.reduce((acc, curr) => {
acc.some(({
type
}) => type == curr.type) ? acc.find(({
type
}) => type == curr.type).img.push(curr.img[0]) : acc.push(curr);
return acc;
}, []);
console.log(newArray);
We use a Set and then a map.
The Set is populate with the unique types by using a map to extract.
We wrap in [] to give us an array the we then re map to build our object back.
The map then rebuilds our objects and note the use of filter and map to get the img values from the original host array.
let oldArray=[
{type:16,img:['1']},
{type:16,img:['2']},
{type:16,img:['3']},
{type:17,img:['4']}
]
let newArray = [...new Set(oldArray.map(e => e.type))]
.map(e => {
return {
type: e,
img: oldArray.filter(i => i.type === e).flatMap(x => x.img)
}
});
console.log(newArray);
This solution is not a reduce but return result you are looking for is the same
let oldArray = [
{type:16,img:['1']},
{type:16,img:['2']},
{type:16,img:['3']},
{type:17,img:['4']}
];
const transitoryMap = new Map();
for (const item of oldArray) {
if (!transitoryMap.has(item.type)) {
transitoryMap.set(item.type, [item.img[0]])
} else {
const value = transitoryMap.get(item.type)
value.push(item.img[0])
transitoryMap.set(item.type, value)
}
}
const newArray = [];
for (const item of transitoryMap.keys()) {
newArray.push({type:item,img:transitoryMap.get(item)})
}
console.log(newArray)
Here is an example using reduce. I have added a tracker to keep track of type in the newArray.
let oldArray = [
{type:16,img:['1']},
{type:16,img:['2']},
{type:16,img:['3']},
{type:17,img:['4']}
];
oldArray.reduce((a,c)=>{
let index = a.tracker.indexOf(c.type);
if(index === -1) {
a.tracker.push(c.type);
a.newArray.push({...c, img:[...c.img]});
} else {
a.newArray[index].img.push(...c.img);
}
return a;
},{tracker:[],newArray:[]}).newArray;
You might want to consider breaking up the processing into separate simple steps, for example:
Create a flattened object with the appropriate data.
build a new array with the wanted structure.
This will not only keep your code simple, but will allow you to focus on what your code is actually doing instead of how it is doing the task.
var oldArray=[
{type:16,img:['1']},
{type:16,img:['2']},
{type:16,img:['3']},
{type:17,img:['4']}
]
flattenMyObject = (arr) =>
arr.reduce((accum, current) => {
!!accum[current.type] ? accum[current.type].push(...current.img) : accum[current.type] = current.img;
return accum;
}, {});
buildNewArray = (type) => {
return {type: type, img: flattenedObject[type] }
}
Object
.keys(flattenMyObject(oldArray))
.map(buildNewArray);
I have some data that comes like an array, i will show you it looks
Vm.table=[{
Name:"amina";
},
{
Prenom:"adfe";
},
{
Region:"rabat";
}];
To an object like
Vm.obj={
Name:"amina",
Prenom:"adfe",
Region:"rabat"
};
I need to set a code that may convert the table to this object, i put a lot of functions but is not working to me if someone can help.
You can use Object.assign() and spread operator
const table=[{Name:"amina"},{Prenom:"adfe"},{Region:"rabat"}];
const result = Object.assign({}, ...table);
console.log(result);
You can use reduce
Vm.obj = Vm.table.reduce((obj, col) => {
Object.keys(col).forEach(k => obj[k] = col[k])
return obj;
}, {});
Of course, if you have repeating keys, this will take the last key/val pair available.
Use Array.prototype.reduce and I am assuning objects have only single key, value pair.
let array =[{
Name:"amina"
},
{
Prenom:"adfe"
},
{
Region:"rabat"
}];
let obj = array.reduce((prev, curr) => {
const key = Object.keys(curr)[0];
prev[key] = curr[key];
return prev;
}, {});
console.log(obj);