Reputation: 618
Goal is to remove the hardcoded database column names from my React component into a config file. Instead of using data.X it would be data.A as shown below. This way if they change X to something else I would just need to change the config file for X and then everywhere in my React component it will update, because data.A is in the component.
Problem is filtering returns only the last object in data. Any help would be appreciated, any suggestions on removing the nested for loop would be helpful for learning.
Desired output:
[
{
"A": 1,
"B": 2,
},
{
"A": 4,
"B": 5,
},
{
"A": 7,
"B": 8,
},
];
Current output:
[
{
"A": 7,
"B": 8,
},
{
"A": 7,
"B": 8,
},
{
"A": 7,
"B": 8,
},
];
let data = [
{
"X": 1,
"Y": 2,
"Z": 3,
},
{
"X": 4,
"Y": 5,
"Z": 6,
},
{
"X": 7,
"Y": 8,
"Z": 9,
},
];
let keys = {
A: 'X',
B: 'Y',
};
let keyChain = {};
let cleanedData = [];
for (let key in keys) {
keyChain[key] = '';
}
for (let i in data) {
cleanedData[i] = keyChain;
for (let key in keys) {
if (keys[key] in data[i]) {
cleanedData[i][key] = data[i][keys[key]];
};
}
}
console.log(cleanedData);
Upvotes: 0
Views: 72
Reputation: 3975
It's way easier to solve than expected. Simply use map
.
let filteredData = data.map((item) => ({'A' : item.X, 'B' : item.Y}));
You are simply mapping element.X
of each item to A
and element.Y
to B
into a new object each time.
let data = [
{
"X": 1,
"Y": 2,
"Z": 3,
},
{
"X": 4,
"Y": 5,
"Z": 6,
},
{
"X": 7,
"Y": 8,
"Z": 9,
},
];
let filteredData = data.map((item) => ({'A' : item.X, 'B' : item.Y}));
console.log(filteredData);
The script above takes 1496412529493.929ms
to complete, while the one in the accepted answer takes 1496412584210.4958ms
which is a bit slower.
Upvotes: 1
Reputation: 221
IMHO what you missed is that the keyChain object is used the same for each cleanedData array element. You must always remember that JavaScript uses references to objects so each line:
cleanedData[i] = keyChain; // same object
// ...
cleanedData[i][key] = data[i][keys[key]];
// modify keyChain object attributes
You have, in result, an array of references to the same object and the value is the last modification.
Try to use something like (ES5 way):
cleanedData[i] = new Object(); // new object
Upvotes: 1
Reputation: 555
const data = [
{
"X": 1,
"Y": 2,
"Z": 3,
},
{
"X": 4,
"Y": 5,
"Z": 6,
},
{
"X": 7,
"Y": 8,
"Z": 9,
},
];
const keys = {
A: 'X',
B: 'Y',
};
let keysReMap = {};
for (var [key, value] of Object.entries(obj)) {
keysReMap[value] = key;
}
const cleanedData = data.map((val, key) => {
const newKey = keysReMap[key];
return {
[newKey]: val
};
});
Upvotes: 0
Reputation: 17064
That's because you're reusing the same keyChain
object as your new placeholder, so that's the same object. You need to create a new one each time:
cleanedData[i] = { ...keyChain }; // instead of cleanedData[i] = keyChain;
Upvotes: 1
Reputation: 7498
Just change your last part of code to the following then you can achieve
for (let i in data) {
cleanedData[i] ={}
for (let key in keys) {
if (keys[key] in data[i]) {
cleanedData[i][key] = data[i][keys[key]];
};
}
}
console.log(cleanedData);
let data = [
{
"X": 1,
"Y": 2,
"Z": 3,
},
{
"X": 4,
"Y": 5,
"Z": 6,
},
{
"X": 7,
"Y": 8,
"Z": 9,
},
];
let keys = {
A: 'X',
B: 'Y',
};
let keyChain = {};
let cleanedData = [];
// construct the placeholder key value pair array
for (let key in keys) {
keyChain[key] = '';
}
// check keys to see if there's a match with the json
for (let i in data) {
cleanedData[i] ={}
for (let key in keys) {
if (keys[key] in data[i]) {
cleanedData[i][key] = data[i][keys[key]];
};
}
}
console.log(cleanedData);
Hope it helps
Upvotes: 1