I have an array that stores various objects. Looks like following:
[ 'key2': { id: 'WA3WA9WA2WA4WAdWA1WA2WAb-WAeWAdWAaWAf-4WA1WAaWA6-WA8WA8WAeWAc-WAfWAdWAbWAeWAaWA5WA1WAfWAbWAdWAfWA2',
d: undefined,
x: 520,
y: 120 },
'Key1': { id: 'WA7WA2WAbWAdWAfWA9WA6WA8-WA7WAdWAeWA4-4WA4WA3WAb-WAaWAdWA4WAe-WA2WAbWAdWA5WA1WA0WA7WAbWA3WAdWAfWA9',
d: undefined,
x: 810,
y: 180 } ]
How do I push a value into the array such as:
['key3':{id:something, d:undefined,x:200,y:400}]
Here Key1, Key2, Key3 are all dynamically created and stored in a variable.
maybe You mean You have a literal like
var yourObj = { 'key1': ...
'key2': ...
}
and You want to push another one? if it's the case do it
yourObj[newKeyGenerated] = theNewObj;
You can have an array
var a = [{ id: 'WA3WA9WA2WA4WAdWA1WA2WAb-WAeWAdWAaWAf-4WA1WAaWA6-WA8WA8WAeWAc-WAfWAdWAbWAeWAaWA5WA1WAfWAbWAdWAfWA2',
d: undefined,
x: 520,
y: 120 },
{ id: 'WA7WA2WAbWAdWAfWA9WA6WA8-WA7WAdWAeWA4-4WA4WA3WAb-WAaWAdWA4WAe-WA2WAbWAdWA5WA1WA0WA7WAbWA3WAdWAfWA9',
d: undefined,
x: 810,
y: 180 } ]
in this case a.push({...})
or an object
var a = { 'key2': { id: 'WA3WA9WA2WA4WAdWA1WA2WAb-WAeWAdWAaWAf-4WA1WAaWA6-WA8WA8WAeWAc-WAfWAdWAbWAeWAaWA5WA1WAfWAbWAdWAfWA2',
d: undefined,
x: 520,
y: 120 },
'Key1': { id: 'WA7WA2WAbWAdWAfWA9WA6WA8-WA7WAdWAeWA4-4WA4WA3WAb-WAaWAdWA4WAe-WA2WAbWAdWA5WA1WA0WA7WAbWA3WAdWAfWA9',
d: undefined,
x: 810,
y: 180 } }
and then you can have a.key3 = {...}
If I have understood correctly , this should be the solution : https://jsfiddle.net/a7uxd4tk/
var data1 = [ {'key1': { id: 'a', d: undefined, x: 520, y: 120 }}];
var data2 = [ {'key2': { id: 'b', d: undefined, x: 520, y: 120 }}];
var data3 = [ {'key3': { id: 'b', d: undefined, x: 520, y: 120 }}];
var addData = [];
addData.push(data1[0]);
addData.push(data2[0]);
addData.push(data3[0]);
console.log(addData);
Also do note [ { and } ]
Try it:
var data = [ {'key2': { id: 'WA3WA9WA2WA4WAdWA1WA2WAb-WAeWAdWAaWAf-4WA1WAaWA6-WA8WA8WAeWAc-WAfWAdWAbWAeWAaWA5WA1WAfWAbWAdWAfWA2',
d: undefined,
x: 520,
y: 120 }},
{'Key1': { id: 'WA7WA2WAbWAdWAfWA9WA6WA8-WA7WAdWAeWA4-4WA4WA3WAb-WAaWAdWA4WAe-WA2WAbWAdWA5WA1WA0WA7WAbWA3WAdWAfWA9',
d: undefined,
x: 810,
y: 180 }} ];
var newObj = {};
newObj.key3 = {};
newObj.key3.id = 'WA3WA9WA2WA4WAdWA1WA2WAb-WAeWAdWAaWAf-4WA1WAaWA6-WA8WA8WAeWAc-WAfWAdWAbWAeWAaWA5WA1WAfWAbWAdWAfWA2';
newObj.key3.d = undefined;
newObj.key3.x = 520;
newObj.key3.y= 120;
data.push(newObj);
console.log(data);
Related
Trying to match each element of an array to a set of coordinates in a multidimensions array in the following manner:
array1= [0, 5, 4]
array2 = [
{x: 1, y: 4, name: 'A', w: 0},
{x: 2, y: 8, name: 'E', w: 4},
{x: 3, y: 1, name: 'F', w: 5}];
I am hoping to match each element of array 1 to the value of w in array 2
0 -> {x: 1, y: 4, name: 'A', w: 0}
5 -> {x: 3, y: 1, name: 'F', w: 5}
4 -> {x: 2, y: 8, name: 'E', w: 4}
I want to return :
[
{x:1, y,4}, {x:3, y:1},
{x:3, y:1}, {x:2, y:8},
...
];
You should return the required x and y coordinates as an array.
Please find a working fiddle for that.
const array1 = [0, 5, 4]
const array2 = [
{ x: 1, y: 4, name: 'A', w: 0 },
{ x: 2, y: 8, name: 'E', w: 4 },
{ x: 3, y: 1, name: 'F', w: 5 },
];
const tempArray = array1.map((item) => array2.find((node) => node.w === item));
// console.log(tempArray);
const finalArray = tempArray.map((currentNode, index, actualArray) => {
const nextIndex = index === actualArray.length - 1 ? 0 : index + 1;
return [
{ x: currentNode.x, y: currentNode.y },
{ x: actualArray[nextIndex].x, y: actualArray[nextIndex].y },
];
});
console.log(finalArray);
You can chain array filter and map to do something like this
Array.prototype.filter() to filter all elements based on the index from first array and
Array.prototype.map() to modify the object so as to only show the x and y co-ordinates
const array1 = [0, 5, 4];
const array2 = [
{ x: 1, y: 4, name: "A", index: 0 },
{ x: 2, y: 8, name: "E", index: 4 },
{ x: 3, y: 1, name: "F", index: 5 },
];
const newArr = array2.filter(x => array1.includes(x.index)).map(x => ({ x: x.x, y: x.y }));
console.log(newArr)
I have a nested object and I want to flatten/map it into a single-layered, table-like object.
[{
a: 1,
b: 2,
c: [{
x: 10,
y: 20
}, {
x: 30,
y: 40
}]
}, {
a: 3,
b: 4,
c: [{
x: 50,
y: 60
}, {
x: 70,
y: 80
}]
}]
From that, I want to get something like this:
[{
a: 1,
b: 2,
x: 10,
y: 20
}, {
a: 1,
b: 2,
x: 30,
y: 40
}, {
a: 3,
b: 4,
x: 50,
y: 60
}, {
a: 3,
b: 4,
x: 70,
y: 80
}]
Sure, I could simply iterate over the object with two for loops and put the result info a separate array, but I wonder, if there is a simpler solution. I already tried to play around with flatMap. It works, if I only want the c portion of my nested object, but I don't know how to map a and b to this object.
As some of you asked for some working code, this should do it (untested):
let result = [];
for (const outer of myObj)
for (const inner of outer.c)
result.push({a: outer.a, b: outer.b, x: inner.x, y: inner.y});
The question is, if there is a functional one-liner or even another, better approach. In reality, my object consists of four layers and the nested for loops become messy quite fast.
You may use flatMap method alongwith map on property 'c':
var input = [{ a: 1, b: 2, c: [{ x: 10, y: 20 }, { x: 30, y: 40 }] }, { a: 3, b: 4, c: [{ x: 50, y: 60 }, { x: 70, y: 80 }] }];
const output = input.flatMap(obj =>
obj.c.map(arr => ({a: obj.a, b: obj.b, x: arr.x, y: arr.y}))
);
console.log(output);
Ideally a solution would require something to tell how far down to start classing the object as been a full object, a simple solution is just to pass the level you want. If you don't want to pass the level, you could do a check and if none of the properties have array's, then you would class this as a complete record, but of course that logic is something you would need to confirm.
If you want a generic version that works with multiple levels were you pass the level & using recursion you could do something like this ->
const a=[{a:1,b:2,c:[{x:10,y:20},{x:30,y:40}]},{a:3,b:4,c:[{x:50,y:60},{x:70,y:80}]}];
function flattern(a, lvl) {
const r = [];
function flat(a, l, o) {
for (const aa of a) {
o = {...o};
for (const [k, v] of Object.entries(aa)) {
if (Array.isArray(v) && l < lvl) flat(v, l + 1, o);
else o[k] = v;
}
if (l === lvl) r.push(o);
}
}
flat(a, 1);
return r;
}
console.log(flattern(a, 2));
//console.log(flattern(a, 1));
A flatMap solution would look like this:
const result = myObj.flatMap(outer =>
outer.c.map(inner =>
({a: outer.a, b: outer.b, x: inner.x, y: inner.y})
)
);
Of course, if your object has multiple layers, not just two, and possibly even multiple or unknown properties that have such a nesting, you should try to implement a recursive solution. Or an iterative one, where you loop over an array of property names (for your example case, ["c"]) and apply the flattening level by level.
One of the solution using reduce is:
const list = [{
a: 1,
b: 2,
c: [{
x: 10,
y: 20
}, {
x: 30,
y: 40
}]
}, {
a: 3,
b: 4,
c: [{
x: 50,
y: 60
}, {
x: 70,
y: 80
}]
}]
const flatten = (arr) => {
return arr.reduce((flattened, item) => {
return [
...flattened,
...item.c.reduce((flattenedItem, i) => {
return [
...flattenedItem,
{
a: item.a,
b: item.b,
x: i.x,
y: i.y
}
]
}, [])
]
}, [])
}
console.log(flatten(list));
Using two reducers to flatten your structure
const input = [{
a: 1,
b: 2,
c: [{
x: 10,
y: 20
}, {
x: 30,
y: 40
}]
}, {
a: 3,
b: 4,
c: [{
x: 50,
y: 60
}, {
x: 70,
y: 80
}]
}]
const result = input.reduce((acc_0, x) => {
return [...acc_0, ...x.c.reduce((acc_1, y) => {
const obj = {
a: x.a,
b: x.b,
x: y.x,
y: y.y
}
acc_1.push(obj);
return acc_1;
}, [])]
}, []);
console.log(result)
im trying to normalize some data sitting in an array of objects.
[
{id: 1, number: 10, x: 0.3, y: 0.4, …}
{id: 2, number: 5, x: 0.5, y: 0.2, …}
{...}
{...}
{...}
]
I want to map the x and y entry's on a new value between 0 - 1250. So I get the following Array of Objects
[
{id: 1, number: 10, x: 375, y: 500, …}
{id: 2, number: 5, x: 625, y: 250, …}
{...}
{...}
{...}
]
Whats the best Practice for that?
Best,
Chris
You can use Array.map
const arr = [
{id: 1, number: 10, x: 0.3, y: 0.4},
{id: 2, number: 5, x: 0.5, y: 0.2}
];
// Use Array.map to iterate
const arr1 = arr.map(ob => {
ob.x*=1250;
ob.y*=1250;
return ob;
});
console.log(arr1);
Some thing like this with map method.
const arr = [
{id: 1, number: 10, x: 0.3, y: 0.4},
{id: 2, number: 5, x: 0.5, y: 0.2},
];
const res = arr.map(({x, y, ...rest}) => ({...rest, x: x * 1250, y: y * 1250 }));
console.log(res)
Assuming arr is your array of object. You can use map which returns new modified array.
let arr = [
{
id: 1, number: 10, x: 0.3, y: 0.4,
},
{
id: 2, number: 5, x: 0.5, y: 0.2
}
];
const normalize = (obj) => {
x = obj.x * 1250;
y = obj.y * 1250;
return {...obj, x, y};
// If you're only using mutating then
// above lines can be
// obj.x *= 1250;
// obj.y *= 1250;
// return obj;
}
// Not mutating array, output new array
const nonMutating = (arr) => {
let newRes = [];
arr.forEach(a => {
newRes.push(normalize(a));
});
return newRes;
}
console.log(nonMutating(arr));
console.log("\n");
// Mutating input array
const mutating = (arr) => {
return arr.map(a => normalize(a));
}
console.log(mutating(arr));
I have an array of objects:
objArray = [
{x: 1, y: 7},
{x: 2, y: 14},
{x: 1, z: 9},
{x: 2, z: 18}
{x: 1, n: 6}
{x: 2, n: 16}
]
Is there an efficient way to merge for "X" without a for loop? so that I end up with:
objArray = [
{x: 1, y: 7, z: 9, n: 6},
{x: 2, y: 14, z: 18, n: 16}
]
So look for common objArray[n]["x"] and merge all hits into one object? It's OK to modify the original array or create a new one.
I'm aware this can be done with a loop, but I'm trying to avoid too many loops for this implementation, though I'm not sure if a reduce or a filter would work for this.
You could take a Map and group by property x.
var array = [{ x: 1, y: 7 }, { x: 2, y: 14 }, { x: 1, z: 9 }, { x: 2, z: 18 }, { x: 1, n: 6 }, { x: 2, n: 16 }],
result = Array.from(
array
.reduce((m, o) => m.set(o.x, Object.assign({}, m.get(o.x), o)), new Map)
.values()
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could use reduce method to build an object and then Object.values to get an array.
const data = [{"x":1,"y":7},{"x":2,"y":14},{"x":1,"z":9},{"x":2,"z":18},{"x":1,"n":6},{"x":2,"n":16}]
const res = data.reduce((r, {x, ...rest}) => {
if(!r[x]) r[x] = {x, ...rest}
else Object.assign(r[x], rest);
return r;
}, {})
const result = Object.values(res);
console.log(result)
You can do it with Array#reduce:
const objArray = [
{x: 1, y: 7},
{x: 2, y: 14},
{x: 1, z: 9},
{x: 2, z: 18},
{x: 1, n: 6},
{x: 2, n: 16},
]
const result = Object.values( objArray.reduce(
(p,c) => (p[c.x] = Object.assign( {}, p[c.x], c ), p ), {}
) );
console.log( result );
I have an object that looks like this:
{
createdAt: "2016-01-25T04:01:53.282Z"
index: 0
objectId: "56a59e31a633bd0257868cb8"
panoDataRotate: 0
roomModelId: "56a59e242e958a00596a897c"
x: 240
y: 230
}
I want to clone it but into an object that only has index,x, andy`:
{
index: 0
x: 240
y: 230
}
How to do that with lodash/Underscore?
With lodash, you could use this:
var obj = {
createdAt: "2016-01-25T04:01:53.282Z",
index: 0,
objectId: "56a59e31a633bd0257868cb8",
panoDataRotate: 0,
roomModelId: "56a59e242e958a00596a897c",
x: 240,
y: 230
};
var newObject = _.pick(obj, ['index', 'x', 'y']);
See here the docs for _.pick() function.
And a plain JavaScript solution:
var obj = {
createdAt: "2016-01-25T04:01:53.282Z",
index: 0,
objectId: "56a59e31a633bd0257868cb8",
panoDataRotate: 0,
roomModelId: "56a59e242e958a00596a897c",
x: 240,
y: 230
};
var newObject = ['index', 'x', 'y'].reduce(function(result, key) {
result[key] = obj[key];
return result;
}, {});
for-in on data
You can use for-in to loop over properties of an object.
var data = {
createdAt: "2016-01-25T04:01:53.282Z",
index: 0,
objectId: "56a59e31a633bd0257868cb8",
panoDataRotate: 0,
roomModelId: "56a59e242e958a00596a897c",
x: 240,
y: 230
}
var allowedKeys = ["x", "y", "index"];
var result = {};
for (var key in data){
if(allowedKeys.indexOf(key)>-1){
result[key] = data[key];
}
}
console.log(result)
forEach over allowedKeys array
You can also loop over array of allowed keys to reduce code.
Note: In this approach, if key is not present in data, undefined will be assigned to it. But in prior approach, this key will be inserted.
For demo purpose, I have added a key test to allowedKeys array.
var data = {
createdAt: "2016-01-25T04:01:53.282Z",
index: 0,
objectId: "56a59e31a633bd0257868cb8",
panoDataRotate: 0,
roomModelId: "56a59e242e958a00596a897c",
x: 240,
y: 230
}
var allowedKeys = ["x", "y", "index", "test"];
var result = {};
allowedKeys.forEach(function(key){
result[key] = data[key];
})
console.log(result)