Rename a subkey of an object with ES6 - javascript

I have a JS object of the following structure:
let data = {
Apples: {
A: 2,
B: 9
},
Oranges: {
C: 4,
D: 8
},
Bananas: {
E: 3,
F: 2
},
Peaches: {
G: 8,
H: 4
},
Pears: {
I: 10,
J: 10
},
Melons: {
K: 4,
L: 7
}
};
I need to rename the subkey dynamically with JS.
For example, I need to rename the key A into New name.
What is the best ES6-enabled way to do it?
I tried to loop through the object using a simple for loop and generate a new object with a renamed key, but it's indeed not the most efficient way!

What about this?
I'm not generating a new object, but adding the new properties to the existing one and deleting the original ones.
let data = {
Apples: {
A: 2,
B: 9
},
Oranges: {
C: 4,
D: 8
},
Bananas: {
E: 3,
F: 2
},
Peaches: {
G: 8,
H: 4
},
Pears: {
I: 10,
J: 10
},
Melons: {
K: 4,
L: 7
}
};
for (let key1 in data) {
const e = data[key1];
for (let key2 in e) {
e["New Name for " + key2] = e[key2];
delete e[key2];
}
}
console.log(data);

Related

How to reassign values in a js object based on the values present in an object within the same object?

I have an array of objects in the following form-
let result = [
{
a: 1,
b: 2,
c: 3,
newValues: {
a: 10,
b: 20,
c: 30
}
},
{
d: 4,
e: 5,
f: 6,
newValues: {
d: 40,
e: 50,
f: 60
}
}
]
And want to convert it to following format -
let result = [
{
a: 10,
b: 20,
c: 30,
},
{
d: 40,
e: 50,
f: 60
}
]
But have been unable to do so.
Any help for converting the older array to the new one will be very much appreciated.
A simple map will do it
let result = [
{
a: 1,
b: 2,
c: 3,
newValues: {
a: 10,
b: 20,
c: 30
}
},
{
d: 4,
e: 5,
f: 6,
newValues: {
d: 40,
e: 50,
f: 60
}
}
]
let data = result.map( r => r.newValues)
console.log(data)
The problem by mapping only the r.newValues is you can potentially lost data that never changed and are not in newValues.
const result = [
{
a: 1,
b: 2,
c: 3,
newValues: {
a: 10,
b: 20,
c: 30
}
},
{
d: 4,
e: 5,
f: 6,
newValues: {
d: 40,
e: 50
}
}
];
const updates = result.map(element => {
const {newValues, rest} = element;
delete element.newValues;
return {...element, ...newValues};
});
console.log(updates);
It will work even if a value of newValues was not present into newValues.
The following answer is roughly equivalent to the one by JStw, with two key differences:
It uses Underscore instead of spread syntax;
It does not modify the elements of result.
This means that code is easier to reason about and potentially safer. Also, you don't need polyfills for the spread syntax.
const result = [
{
a: 1,
b: 2,
c: 3,
newValues: {
a: 10,
b: 20,
c: 30
}
},
{
d: 4,
e: 5,
f: 6,
newValues: {
d: 40,
e: 50
}
}
];
const updates = _.map(result, element =>
_.chain(element)
.omit('newValues')
.extend(element.newValues)
.value()
);
console.log(updates);
<script src="https://cdn.jsdelivr.net/npm/underscore#1.13.6/underscore-umd-min.js"></script>

Delete property and its values in all the object

I'm a beginner in javaScript, I have this object MyGraph:
const MyGraph = {
a: { b: 5, c: 2 },
b: { a: 5, c: 7, d: 8 },
c: { a: 2, b: 7, d: 4, e: 8 },
};
I want to delete property "a" and its values in other properties as well to get this result:
const MyGraph = {
b: { c: 7, d: 8 },
c: { b: 7, d: 4, e: 8 },
};
I tried like this:
for(let XXX of Object.keys(MyGraph)){
console.log(XXX.a);
delete XXX.a;
}
the result of execution:
undefined
undefined
undefined
any help!
You could use a recursive algorithm :
function del_entries(key, obj) {
if (obj.hasOwnProperty(key)) {
delete obj[key];
}
// Or with Object.hasOwn, not fully supported by old browsers but more up to date
/*
if (Object.hasOwn(obj, key)) {
delete obj[key]
}
*/
Object.values(obj).forEach(o=> del_entries(key, o))
}
const MyGraph = {
a: { b: 5, c: 2 },
b: { a: 5, c: 7, d: 8 },
c: { a: 2, b: 7, d: 4, e: 8 },
};
del_entries("a", MyGraph);
console.log(MyGraph)
In your code XXX is the key. You need to do graph[XXX] to access the actual object. So instead of XXX.a you should do graph[XXX].a. But this only accounts for objects in graph that have an the key a. You also need to account for key a in graph. Please see the code below. Its a rudimentary example.
If you have one level of nesting then you can use then you can use the code below.
const mygraph = {
a: { b: 5, c: 2 },
b: { a: 5, c: 7, d: 8 },
c: { a: 2, b: 7, d: 4, e: 8 },
};
console.log(mygraph);
function deletePropAndValuesOf(key, graph) {
for (const k of Object.keys(graph)) {
if (k === key) {
delete graph[key];
} else {
if (key in graph[k]) {
delete graph[k][key]
}
}
}
}
deletePropAndValuesOf("a", graph);
console.log(mygraph);
You can copy the code to a .js file and run it using node. e.g.
Ive used object destructuring to remove the first array with an a, but could not figure out how to do all the a's's but the code below might help?
const MyGraph = {
a: { b: 5, c: 2 },
b: { a: 5, c: 7, d: 8 },
c: { a: 2, b: 7, d: 4, e: 8 }};
const {a, ...newMyGraph} = MyGraph;
// output
console.log(newMyGraph)
returns
b: {
a: 5,
c: 7,
d: 8
},
c: {
a: 2,
b: 7,
d: 4,
e: 8
}
}

How to flatten object of objects recursively into array

I have an object like this:
const myObj = {
a: {
b: {
c: 1,
d: 2
},
f: {
z: 4,
u: 6
}
}
}
into this:
const myObj = [
{
c: 1,
d: 2,
},
{
z: 4,
u: 6,
}
]
I found this: How to recursively transform an array of nested objects into array of flat objects? but the original is an array of objects, and mine is an object itself.
You can traverse the values of the objects until you reach the leaves (objects with no values that are other objects).
const myObj = {
a: {
b: {
c: 1,
d: 2
},
f: {
z: 4,
u: 6
}
}
};
const flatObj = o => Object.values(o).some(x => x === Object(x)) ?
Object.values(o).flatMap(flatObj) : [o];
console.log(flatObj(myObj))

javascript, convert an array of objects to an array of arrays vertically

I have a CSV file that I have successfully read in with d3.csv. The result is a JSON file where each line consists of an array element and each array element is an object with key/value pairs matching the column headers.
I need this in a "vertical" format, as an array of arrays, where each inner array consists of the value for each object.
Here is an example to run in Node:
> a = new Array();
[]
> a.push({"b":2, "c": 4, "d":6, "e": 8});
1
> a.push({"b":3, "c": 6, "d":9, "e": 12});
2
> a.push({"b":4, "c": 8, "d":12, "e": 16});
3
> a.push({"b":5, "c": 10, "d":15, "e": 20});
4
> a
[
{ b: 2, c: 4, d: 6, e: 8 },
{ b: 3, c: 6, d: 9, e: 12 },
{ b: 4, c: 8, d: 12, e: 16 },
{ b: 5, c: 10, d: 15, e: 20 }
]
> x = [[2,3,4,5],[4,6,8,10],[6,9,12,15],[8,12,16,20]]
[ [ 2, 3, 4, 5 ], [ 4, 6, 8, 10 ], [ 6, 9, 12, 15 ], [ 8, 12, 16, 20 ] ]
> x
[
[ 2, 3, 4, 5 ],
[ 4, 6, 8, 10 ],
[ 6, 9, 12, 15 ],
[ 8, 12, 16, 20 ]
]
>
Here, [a] represents the array of object I have while [x] represents the array of arrays I would like to have.
My data file is very wide and has many columns. I have tried several toy solutions, and I can iterate through the array, select each element, then iterate through each element and select each key, grab the value, and push it to a new array. However, this is nasty and very easy to break. Surely there is a better way.
If I had a list of lists, I could flip the rows and columns. Unfortunately, I have a list of object, read in with D3.csv().
My primary language was (note, was) Perl, and a Perl-ish solution is natural to me. My current application runs client side in a browser, and I need a client side solution in JavaScript.
You can achieve this in a number of ways, but since it appears that all objects in your source array have the same properties, the most direct may be a nested map() call. The outer map() is called on the Object.keys() of the first element of the array, and the inner map() uses each iterated key on every object in the source array.
const a = [{ b: 2, c: 4, d: 6, e: 8 }, { b: 3, c: 6, d: 9, e: 12 }, { b: 4, c: 8, d: 12, e: 16 }, { b: 5, c: 10, d: 15, e: 20 }];
const result = Object.keys(a[0]).map(key => a.map(o => o[key]));
console.log(result);
If the objects had varying properties, you could use a reduce() call to accumulate all the values of like properties.
const a = [{ b: 2, c: 4, d: 6, e: 8 }, { b: 3, c: 6, d: 9, e: 12 }, { b: 4, c: 8, d: 12, e: 16 }, { b: 5, c: 10, d: 15, e: 20 }];
const result = Object.values(
a.reduce((acc, obj) => {
Object.keys(obj).forEach(key =>
(acc[key] ??= []).push(obj[key]));
return acc;
}, {}));
console.log(result);
I like #pilchard's d3 agnostic answer; but if you're interested in a d3 driven answer you can use d3.transpose on an array of arrays with a pre-processing step of removing the keys of the objects with Object.values:
const a = [
{ b: 2, c: 4, d: 6, e: 8 },
{ b: 3, c: 6, d: 9, e: 12 },
{ b: 4, c: 8, d: 12, e: 16 },
{ b: 5, c: 10, d: 15, e: 20 }
]
const x = d3.transpose(a.map(o => Object.values(o)));
console.log(x);
.as-console-wrapper { max-height: 100% !important; top: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.5.0/d3.min.js"></script>

Adding a new element to an object in an array

Lets say I have and array made up of objects:
var points = [
{ id: 1, a: 0, b: 3 },
{ id: 2, a: 4, b: -1 },
{ id: 3, a: -1, b: 5 },
{ id: 4, a: 41, b: 2 },
{ id: 5, a: 69, b: 3 },
]
I want to iterate through each item and add a + b to get a new item d. I then want to add d within each object in the array to get a new value. When I try the below, it just adds 5 extra objects rather than appending the new element (key=value, ex: d: 3) to each individual object. What am I doing wrong here?
points.forEach((item) => {
var d = Math.abs(item.x) + Math.abs(item.y);
console.log(d);
points.item.push('d: ' + d);
});
Try following
var points = [{ id: 1, a: 0, b: 3 },{ id: 2, a: 4, b: -1 },{ id: 3, a: -1, b: 5 },{ id: 4, a: 41, b: 2 },{ id: 5, a: 69, b: 3 }];
points.forEach(o => o.d = Math.abs(o.a) + Math.abs(o.b));
console.log(points);
#jcbridwe, you can use assign() method on Object to add missing property from source object to target object.
Please have a look at the below code.
Try the below code online at http://rextester.com/EPHYV10615.
var points = [
{ id: 1, a: 0, b: 3 },
{ id: 2, a: 4, b: -1 },
{ id: 3, a: -1, b: 5 },
{ id: 4, a: 41, b: 2 },
{ id: 5, a: 69, b: 3 },
]
for(var index in points){
var a = points[index].a;
var b = points[index].b;
Object.assign(points[index], {d: a+b});
}
console.log(points);
ยป Output
[ { id: 1, a: 0, b: 3, d: 3 },
{ id: 2, a: 4, b: -1, d: 3 },
{ id: 3, a: -1, b: 5, d: 4 },
{ id: 4, a: 41, b: 2, d: 43 },
{ id: 5, a: 69, b: 3, d: 72 } ]
Mutable approach:
points.forEach(o => o.d = o.a + o.b);
Immutable approach:
const newPoints = points.map(o => Object.assign({}, o, {d: o.a + o.b}))

Categories

Resources