I have an array which looks like this
arcAxis:
0:{x: 1.2858791391047208e-15, y: 21}
1:{x: -21, y: 21.000000000000004}
2:{x: -35.8492424049175, y: 6.150757595082504}
3:{x: -39.40038395815852, y: -14.546812157640753}
4:{x: -32.12697787933814, y: -34.24700413672001}
5:{x: -16.811252024253655, y: -48.61462542668643}
6:{x: 3.0355856977321465, y: -55.47779032614515}
Now I have a function which draws elements using x and y of arcAxis.
What I want to do is to call that function to draw an element for each of arcAxis's index value something like this
function test() {
plot(0. x, 0. y)
}
.....
function test() {
plot(6. x, 6. y)
}
So, that I have 6 new elements made on different x,y values respective to their indexes
my approach is printing each element 6 times then printing next element 6 times
function test() {
const arcAxis = this.spiral();
for (var z in arcAxis) {
plot(arcAxis[z].x, arcAxis[z].x)
}
}
Anyway, can I print each element only 1 time with only 1 indexes value?
let data= {
arcAxis:[
{x: 1.2858791391047208e-15, y: 21},
{x: -21, y: 21.000000000000004},
{x: -35.8492424049175, y: 6.150757595082504},
{x: -39.40038395815852, y: -14.546812157640753},
{x: -32.12697787933814, y: -34.24700413672001},
{x: -16.811252024253655, y: -48.61462542668643},
{x: 3.0355856977321465, y: -55.47779032614515}
]
}
data.arcAxis.forEach(({x, y})=>{
plot(x,y);
})
function plot(x,y){
console.log("X: ", x,"Y: ", y );
}
If you are using a pre EcmaScript 6 version:
arcAxis.forEach(function(element) {
plot(element.x, element.y);
});
And for EcmaScript 6 and onwards:
arcAxis.forEach(element => plot(element.x, element.y));
Related
This question already has answers here:
What is 'Currying'?
(23 answers)
Closed 1 year ago.
so I'm struggling to understand this code. Can someone please explain how does function move works? Like I watched a lecture about it, but I still don't understand it.
const parse = (point) => {
return typeof point === "object" ? point : JSON.parse(point);
};
const move = (offset) => (point) =>{
point.x += offset.x;
point.y += offset.y;
return point
};
const polyline = [
{ x: 0, y: 0 },
{ x: 10, y: 10 },
'{ "x": 20, "y": 20 }',
{ x: 30, y: 30 },
];
const offset = move({ x: 10, y: -5 });
const path = polyline.map(parse).map(offset);
console.log({ path });
Here's how it was done previously, and this code is an optimised version of that code:
const shift = (offset, points) => {
let modifiedPoints = [];
points.forEach((point) => {
point = parse(point);
point.x += offset.x;
point.y += offset.y;
modifiedPoints.push(point);
});
return modifiedPoints;
};
It is called currying
The passed created function will in your case add 10 to x and subtract 5 from y from each of the polylines in the array
If you call it with
move({ x: 5, y: -15 }); it will offset each line by 5,-15
const parse = (point) => {
return typeof point === "object" ? point : JSON.parse(point); // did we get an object or a string? if the latter parse it
};
// move takes an offset and returns a function that uses that offset (closure)
const move = (offset) => (point) =>{
point.x += offset.x;
point.y += offset.y;
return point
};
// an array of objects or valid JSON strings
const polyline = [
{ x: 0, y: 0 },
{ x: 10, y: 10 },
'{ "x": 20, "y": 20 }', // this will be parsed
{ x: 30, y: 30 },
];
const offset = move({ x: 10, y: -5 }); // offset is returning a function to be used in the map
const path = polyline.map(parse).map(offset); // call the function for each parsed entry in the polyline
console.log({ path });
This question already has answers here:
One-liner to take some properties from object in ES 6
(12 answers)
Closed 4 years ago.
I would like to create an new object from a bigger one, by copying only a few properties from it. All the solutions I know are not very elegant, I wonder if there is a better choice, native if possible (no additional function like at the end of the following code)?
Here is what I usually do for now:
// I want to keep only x, y, and z properties:
let source = {
x: 120,
y: 200,
z: 150,
radius: 10,
color: 'red',
};
// 1st method (not elegant, especially with even more properties):
let coords1 = {
x: source.x,
y: source.y,
z: source.z,
};
// 2nd method (problem: it pollutes the current scope):
let {x, y, z} = source, coords2 = {x, y, z};
// 3rd method (quite hard to read for such simple task):
let coords3 = {};
for (let attr of ['x','y','z']) coords3[attr] = source[attr];
// Similar to the 3rd method, using a function:
function extract(src, ...props) {
let obj = {};
props.map(prop => obj[prop] = src[prop]);
return obj;
}
let coords4 = extract(source, 'x', 'y', 'z');
One way to do it is through object destructuring and an arrow function:
let source = {
x: 120,
y: 200,
z: 150,
radius: 10,
color: 'red',
};
let result = (({ x, y, z }) => ({ x, y, z }))(source);
console.log(result);
The way this works is that the arrow function (({ x, y, z }) => ({ x, y, z })) is immediately called with source as the parameter. It destructures source into x, y, and z, and then immediately returns those as a new object.
You can do it like below via Spread Operator
let source = {
x: 120,
y: 200,
z: 150,
radius: 10,
color: 'red',
};
let {radius, color, ...newObj} = source;
console.log(newObj);
Just take a function.
const extract = ({ x, y, z }) => ({ x, y, z });
let source = { x: 120, y: 200, z: 150, radius: 10, color: 'red' };
console.log(extract(source));
Another solution is a destructuring to a target object with target properties.
let source = { x: 120, y: 200, z: 150, radius: 10, color: 'red' },
target = {};
({ x: target.x, y: target.y, z: target.z } = source);
console.log(target);
IIFE with destructuring maybe?:
const coords = (({x, y, z}) => ({x, y, z}))(source);
1st method is elegant and readable.
Please don't obfuscate simple operations by some workarounds. Other people who will need to maintain this code, including future yourself will be very thankful in the future.
For simple cases like this the object destructuring mentioned in other answers is very neat but tends to look a bit cumbersome when dealing with larger structures as you double up on property names.
Expanding on your own answer - if you were going to write an extract utility (I'll roll my own for fun)... you can make it more flexible by currying it - allowing you to swap the order of the arguments (notably putting the data source last) while still being variadic in accepting property names.
I'd consider this signature: extract = (...props) => src => { ... } more elegant as it allows for a greater degree of reuse in composing new, named functions:
const extract = (...props) => src =>
Object.entries(src).reduce(
(obj, [key, val]) => (
props.includes(key) && (obj[key] = val),
obj
), {})
const getCoords = extract('x', 'y', 'z')
const source = {
x: 120,
y: 200,
z: 150,
radius: 10,
color: 'red'
}
console.log(getCoords(source))
You can try reduce over [x,y,z] array:
let source = {
x: 120,
y: 200,
z: 150,
radius: 10,
color: 'red',
};
const coords = ['x','y','z'].reduce((a,c) => Object.assign(a,{[c]: source[c]}), {});
console.log(coords);
I would like to be able to get and use the key of a selected object in js
Lets say I have the following object that contains other objects
verts = { A: {x: 7.5, y: 0, z: -7.5}, B: {x: 0, y: 0, z: -15 }
If I can access item A for example with the following;
console.log(verts.A)
It will show me the value within the object (i.e. x: 7.5, y: 0, z: -7.5) but I do not know how to access the selected objects key i.e. in this case "A". I would like to be able to store it as a variable for use as a string later on. It feels like I should be able to write this.key or this[key] somewhere somehow but I cannot find an appropriate answer on here. I am using jquery so if there is a quick way using that thank you.
Thanks for any advice as ever
Once you've read an object using a key, there is no longer a link back to the key you used.
The best thing you can do is store the key you're using in a variable and then use square bracket notation to read it:
var verts = { A: {x: 7.5, y: 0, z: -7.5}, B: {x: 0, y: 0, z: -15 } };
var key = 'A';
var result = verts[key];
console.log(key, result);
Another option is to run your initial object through a pre-processor to build this link:
function preProcess(input){
return Object.keys(input).reduce( function(p,c){
var newObj = input[c];
newObj._key = c;
p[c] = newObj
return p
},{});
}
var verts = { A: {x: 7.5, y: 0, z: -7.5}, B: {x: 0, y: 0, z: -15 } };
var vertsWithKeys = preProcess(verts);
var item = verts.A;
console.log(item._key, item);
You're making this more complicated than it has to be. If you know at some point which keys you're using (and it seems you do), then all you need to do is ensure that those keys are passed along to whatever it is that needs them.
Like this:
//vertices stored as objects
verts = { A: {x: 7.5, y: 0, z: -7.5}, B: {x: 0, y: 0, z: -15}, C: {x: 0, y: 0, z: -7.5} }
//make a triangle using accessed vertices
makeTriangle(verts, 'A', 'B', 'C')
function makeTriangle(vertices, key1, key2, key3){
$("example").append('\
<a-triangle\
id="' + key1 + '_'+ key2 + '_'+ key3 + '"\
vertex-a="' + vertices[key1](joined) + '"\
vertex-b="' + vertices[key2](joined) + '"\
vertex-c="' + vertices[key3](joined) + '"\
</a-triangle>');
}
I'm a little confused with my array creation. I have a list of items with x:y co ordinates and also their dimensions (in grid sizes) ... for example:
x: 1
y: 7
width: 2 tiles
height: 2 tiles
So the idea im trying to do is create an array of x:y grids that are "occupied". But looping such data so the occupied tiles would there for be:
x: 1
y: 7
//
x: 2
y: 7
//
x: 1
y: 8
//
x: 2
y: 8
Because in the above example the item is 2 by 2 tiles ( a square ).
My object is structured like this (shown in console.log(sdata);)
7: Array[4]
0: "1"
1: "7"
2: "2"
3: "2"
So yeah im trying to make an array to store this kind of grid reference..Hope I explained what I trying to get at, but i can't work out how to structure a loop to create the array.
http://jsfiddle.net/rlemon/JeeV2/ Here is an example of how you could produce this type of 'grid' occupied data..
var chords = [ // instead of arrays we'll use objects.. they're nicer.
{
x: 1,
y: 7,
h: 2, // height
w: 2}, // width
{ // ohh look a second plot point.
x: 4,
y: 1,
h: 3,
w: 2},
];
var occupied = { // will be your cells points occupied
x: [],
y: []
};
chords.forEach(function(chord) { // now lets loop the chords and produce the occupied array
occupied.x.push( chord.x );
occupied.x.push( chord.x + (chord.w-1) ); // expand the width of the cell - initial point
occupied.y.push( chord.y );
occupied.y.push( chord.y + (chord.h-1) ); // expand the height of the cell - initial point
});
console.log( occupied );
// outputs
Object
x: Array[4]
0: 1
1: 2
2: 4
3: 5
y: Array[4]
0: 7
1: 8
2: 1
3: 3
The resulting outputArray array is a collection of objects in the form { x: value, y: value}.
var inputArray = [ [1,7,2,2], ... ];
var outputArray = [];
for(var i = 0; i < inputArray.length; i++) {
var item = {
x: inputArray[i][0],
y: inputArray[i][1],
width: inputArray[i][2],
height: inputArray[i][3]
};
for(var xx = 0; xx < item.width; xx++) {
for(var yy = 0; yy < item.height; yy++) {
outputArray.push({
x: item.x + xx,
y: item.y + yy
});
}
}
}
I added the x, y, width and height attributes to make it more understandable.
function range(a, b) {
/*
range(5) -> [0,1,2,3,4]
range(1,4) -> [1,2,3]
*/
if (b===undefined)
var start=0, stop=a;
else
var start=a, stop=b;
var R = [];
for(var i=start; i<stop; i++)
R.push(i);
return R;
}
Then it's a two-liner:
range(x, x+width).map(function(x) {
return range(y, y+height).map(function(y) {
return {x:x, y:y}; // anything you'd like
})
})
Result (obtained via JSON.stringify):
[
[ {"x":1,"y":7}, {"x":1,"y":8} ],
[ {"x":2,"y":7}, {"x":2,"y":8} ]
]
I need to format an array from a list of values.
Currently I have the following hard-coded points:
points = [
{x: 20, y: 112},
{x: 23, y: 101},
{x: 51, y: 89},
{x: 63, y: 89},
{x: 84, y: 129},
{x: 64, y: 153},
{x: 45, y: 151},
{x: 38, y: 140},
{x: 28, y: 150},
{x: 10, y: 144},
{x: 0, y: 130},
{x: 10, y: 114}
];
The resulting array is to be passed to a function.
I now need to pass another array to the same function but I cannot hard-coded them as above. Instead, I am using a JS framework to grab the points dynamically using, for example, $(#container).get('points');
How do I convert the new array so that it is formatted similarly to the x: | y: structure as above?
points="20,112, 23,101, 51,89, 63,89, 84,129, 64,153, 45,151, 38,140, 28,150, 10,144, 0,130, 10,114"
I found the following in MooTools:
Array.each([1, 2, 3], function(number, index)
{
alert('x:' + number + ', y: ' + index);
});
...but somehow that doesn't seem like the correct way to do this.
Can I get a little guidance please?
You can split [docs] the string and iterate over it, taking two values in each iteration:
var parts = points.split(',');
var pointsArray = [];
for(var i = 0, l = parts.length; i < l; i += 2) {
pointsArray.push({x: +parts[i], y: +parts[i+1]});
}
You should actualy split it twice:
var points = "12,12, 1,2, 3,4"
var arr = points.split(', ');
for(var i = 0; i< arr.length; i++)
{
var point = arr[i].split(',');
document.write(point+ ' <br />' );
arr[i] = {x:point[0], y:point[1]};
document.write(' '+arr[i].x + ' ' + arr[i].y + ' <br/>');
}
Apart from that, just like the other comment.