How to change from array of values to array of objects? - javascript

I got data like this:
{"my_data":{"labels":[1,2,3,...], "idx":["idx1", "idx2", ...]}}
But I need it like this:
["my_data":{"labels":1, "idx": "idx1"},{"labels":2, "idx": "idx2"},... ]
I tried to loop like this to change the format:
var arr = [];
for (let [key, value] of Object.entries(my_data)) {
arr.push({[key]:value});
}
console.log(key, value);
But the result is a format I can not use with ag-grid
labels: [1,2,...]
idx: [idx1, idx2,...]

One way you can approach this is by using the map method like in the following example:
const temp = { my_data: { labels: [1, 2, 3], idx: ["idx1", "idx2", "idx3"] } };
const result = temp.my_data.labels.map((label, index) => {
const idx = temp.my_data.idx[index];
return {
label,
idx
};
});
console.log(result)
This way, you're mapping through labels then extracting the value for idx based on the index of the label.

Related

Get all Indexes of Objects in Array - from Array in Object

i´m struggling with a Array in a Object stored in a Array with Objects from which I want return all Indicies.
Function to generate Object looks like this:
const addArray = function(a, b) {
const object = {
name: a,
rooms: b
};
testArray.push(object);
};
What I want to achieve is to cycle through the "testArray" and return every Index from the Object where the Array Rooms contains "Office" for example.
I´ve already tried to use a function like this but I don´t seem to be able to get the right Syntax for the Array in the Object:
function getAllIndexes(arr, val) {
var indexes = [], i = -1;
while ((i = arr.rooms.indexOf(val, i+1)) != -1){
indexes.push(i);
}
return indexes;
};
Thanks in advance!
Edit:
Additional Informations to Data:
A Object with data filled would look like this:
const device = {
name: "TV",
rooms: ["Living Room", "Bedroom"]
};
After generating Objects like this I push them to an array witch only contains this objects (see function addArray)
You can use Array.flatMap() to map each value of the array at matches val to it's index, and the rest to empty array, which will be removed by the flatMap:
const getAllIndexes =(arr, val) => arr.flatMap((v, i) => v === val ? i : [])
const arr = [1, 2, 3, 1, 2, 1, 1, 2]
const result = getAllIndexes(arr, 1)
console.log(result)
Using your array of objects, you'll need to compare a value, or check if an object meets some condition. It's better in this case to replace val with a predicate function:
const getAllIndexes =(arr, pred) => arr.flatMap((v, i) => pred(v) ? i : [])
const arr = [{ rooms: [1, 2, 3] }, { rooms: [2, 1, 1] }, { rooms: [3, 2, 2] }, { rooms: [1, 2, 1] }]
const result = getAllIndexes(arr, o => o.rooms.includes(1))
console.log(result)
Try using Array.prototype.map and Array.prototype.filter
function getAllIndexes(arr, val) {
return arr.map(i=> {
let room = i.rooms;
return room.indexOf(val);
}).filter(a=>{
a != -1;
});
};
You could destructure rooms from the device and get the index, if the wanted value is found.
const
room = 'Office',
indices = array.flatMap(({ rooms }, i) => rooms.includes(room) ? i : []);
The above code features a former solution from me with hacking Array#flatMap.

How to change json data format from array to array of objects with javascript?

I am trying to load data into ag-grid so I got the json data like this format:
{"my_data":{"labels":[1,2,3,...], "idx":["idx1", "idx2", ...]}}
I need it to be like this to pass it to the grid:
{"my_data":[{"labels": 1}, {"labels": 2}, ..., {"idx":"idx1"}, {"idx":"idx2"}, ...}]
Is there a fast way to do it this format or I have to loop through the data using reduce or map ?
desired format example: https://www.ag-grid.com/sample-data/monthlySales.json
I tried to load the data like this
var obj = $.parseJSON(JSON.stringify(data));
gridOptions.api.setRowData(obj.mydata.labels);
Use reduce will simplify.
const data = { my_data: { labels: [1, 2, 3], idx: ["idx1", "idx2"] } };
const updated = Object.entries(data.my_data).reduce((acc, [key, value]) => {
value.forEach(item => acc.push({ [key]: item }));
return acc;
}, []);
const data_updated = { my_data: updated };
console.log(data_updated);

how to convert nested array of objects to object of array

I have got array of nested array of objects .
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
I want to convert array to this format of objects and I want to get this output
let permission ={
group:["1"],
topGroup:["2"]
}
How can I do this ?
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
const converted = data.reduce((a,b) => {
const onlyKey = Object.keys(b)[0];
a[onlyKey] = b[onlyKey].map(i => i.label);
return a;
}, {})
console.log(converted)
const data = [ {group: [{label:"1"}]}, {topGroup: [{label:"2"}]} ]
let permission = {};
data.forEach(val =>{
for(prop in val){
permission[prop] = [val[prop][0]["label"]]
}
})
console.log(permission)
Give this a upvote if this is what you want.
Assuming the data is going to have labels as in that format forever, you could use something like that
const data = [{"group":[{"label":"1"}]},{"topGroup":[{"label":"12"}]}];
// The dict variable under here is the second parameter of reduce that I passed it `{}`.
// The ind variable is the data at the index of the array.
var newData = data.reduce(function(dict, ind){
// You basically get the keys and the values and put them in place
// and return the last state to the reduce function.
dict[Object.keys(ind)] = Object.values(ind)[0][0]["label"];
return dict;
}, {})
console.log(newData)
Use destructuring and Object.fromEntries.
const data = [{ group: [{ label: "1" }] }, { topGroup: [{ label: "2" }] }];
const permission = Object.fromEntries(
data.map(item => {
const [[key, [obj]]] = Object.entries(item);
return [key, Object.values(obj)];
})
);
console.log(permission);

Pick the array by property name from another array

I have an array like that
I want to pick the array item by property name, I am using lodash for that:
const result = _.map(this.thing, _.property('groups')).filter(x => x !== undefined);
But I am getting array of arrays as result
What I need is just single selected property array.
Any idea how to achieve that?
Try this>>>
var a = [{"p1":[3,4]},{"p2":[6,7]}];
function getArr(arr,key){
var res = [];
for(var v of arr){
if(v[key]!=undefined){
res = v[key];break;
}
};
return res;
}
console.log(getArr(a,"p1"));
If you can use ES6/ES7, you can rely on Object.keys and Object.values to access to the key (that is the property name) and the value (the array you want to get):
var arr = [
{ groups: [1, 2 ] },
{ category: [1, 2, 3 ] },
{ subCategory: [1, 2, 3, 4 ] }
];
function pickArray(propertyName) {
var element = arr.find(el => Object.keys(el)[0] === propertyName)
return element ? Object.values(element)[0] : null;
}
var res = pickArray('category');
console.log(res);
const output
= (Array.from(arr, (obj) => obj['product'], 'product')
.filter(x => typeof x !== 'undefined'))[0];
Try this:
const arr = [ {'groups': ['item1','item2']},
{'categories':['x','y']}
]
var ouptut= arr.find(item=> {
return item[Object.keys(item).find(key=>key === 'groups')]
})
console.log(ouptut)

Spread syntax not working as expected with array of objects

I have a react component where I am trying to spread objects into the state in the constructor.
constructor() {
super()
const shapesArray = [1, 2, 3]
let renderStates = shapesArray.map((el, i) => {
return {['shape'+i]: 'black'}
})
this.state = { ...renderStates }
console.log(this.state)
}
I want to access the colors by doing this.state.shape0,
but when I console log this.state, I get this:
instead of Object {shape0: "black", shape1: "black", shape2: "black"}.
What am I doing wrong here?
That is because you are spreading an Array into an Object. Arrays are actually objects with (usually) sequential integral strings as their keys. These keys are the indices of the array.
As shown below, map takes an array and produces another array
const shapesArray = [1, 2, 3];
const renderStates = shapesArray.map((el, i) => {
return {
['shape' + i]: 'black'
}
});
console.log(renderStates);
When spreading into an Object, the value of each own enumerable property in the source Object is added to the target under its respective key. Since the keys of an array are its indices you end up with an Object with a property for each element of the Array. The name of each property is its index in the array.
To achieve what you want, you can use Array.prototype.reduce to build an object from the array with the names created in the mapping process.
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.map((el, i) => {
return {
['shape' + i]: 'black'
}
})
.reduce((o, element) => {
Object.keys(element).forEach(key => o[key] = element[key]);
return o;
}, {});
console.log(renderStates);
Of course this itself can be written more elegantly by spreading the object inside of reduce.
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.map((el, i) => {
return {
['shape' + i]: 'black'
}
})
.reduce((o, element) => ({...o, ...element}), {});
console.log(renderStates);
As an optimization to aluan-haddad's answer, reduce can handle the logic that was in map
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.reduce((acc, _, i) => ({
...acc,
['shape' + i]: 'black',
}), {});
console.log(renderStates);
renderStates is an array which has integer properties starting from 0 or the array indices if you want to be specific, so {...renderStates} will take each index, and create a mapping from this index to the value corresponding to that index, to achieve what you are looking for, you need to reduce your renderStates array to an object like so
let renderStates = shapesArray.map((el, i) => {
return {['shape'+i]: 'black'}
}).reduce((resultObj, currentShape,index) => resultObj['shape'+index] = currentShape['shape'+index]), { });
renderStates is now an object, and you can spread it and it will produce the result you want
No need to iterate twice over array. Use reduce:
const shapesArray = [1, 2, 3];
const renderStates = shapesArray.reduce((accumulator, i) => {
accumulator['shape' + i] = 'black';
return accumulator;
}, {});
console.log(renderStates);

Categories