So lets say I have a log in google's console like this
[[296,279],[304,280],[308,280],[312,280]]
from my script here below
evtSource.onmessage = function(e) {
var obj = JSON.parse(e.data);
var line = JSON.stringify(obj.line)
var size = JSON.stringify(obj.lineWidth)
var color = JSON.stringify(obj.lineColor) // Not needed, but defined anyways.
var chat = JSON.stringify(obj.msg)
if (obj.ident === "") //mee
{
$.post("/draw.php?ing=_index", {
l: (line),
w : parseInt(obj.lineWidth) + 2,
c: ("ffffff"),
o: ("100"),
f: ("1"),
_: ("false")
})
console.log(line) //Logs the line. (Example in question.)
How could I add a value of 20 to each item in the array when it logs.
So it will log something like this
[[316,299],[324,300],[328,300],[332,300]]
and not like this (The original.)
[[296,279],[304,280],[308,280],[312,280]]
Use map:
const arr = [
[296, 279],
[304, 280],
[308, 280],
[312, 280]
];
const res = arr.map(e => e.map(f => f + 20));
console.log(res);
.as-console-wrapper {
max-height: 100% !important;
top: auto;
}
If you want to print the array with altered data but without altering the original you probably want to use JSON.stringify and JSON.parse to copy the array.
JSON.stringify also accepts a second parameter that allows you to edit the values while the object is being stringified.
var original = [
[296, 279],
[304, 280],
[308, 280],
[312, 280],
[[58, 60], [75, 84]],
4,
[[5, 9], [[0], [-3]], 8]
];
var json = JSON.stringify(original, function(key, value) {
return typeof value === "number" ? value + 20 : value;
});
console.log(json);
console.log(JSON.parse(json));
This will work, regardless of how many dimensions the array has (and is ES5 compatible).
You can use Array.map function.
Here we provide a function which will be executed with each element of the array. Which in your case will be another map function.
const line = [[296, 279],[304, 280],[308, 280],[312, 280]]
const out = line.map(arr => arr.map(x => x + 20))
console.log(out)
Related
I have four variables and I want to change their values using a function where I just can put in an array storing the variables. I'm making a game which uses a coordinate system and therefore I have four coordinates that I want to constantly update with y-axis and x-axis. I have one array, yAxis, with all y values and one array, xAxis, with all x values. I want to combine them into the coordinates. Of course, I can update them using the following code:
yAxis = [10, 10, 9, 9];
xAxis = [4, 4, 5, 5];
coordinate1 = "" + yAxis[0] + xAxis[0];
coordinate2 = "" + yAxis[1] + xAxis[1];
coordinate3 = "" + yAxis[2] + xAxis[2];
coordinate4 = "" + yAxis[3] + xAxis[3];
But instead of changing their values like earlier I would like to do something like this: This function will take the array below, coordinatesArray as a, yAxis as b, and xAxis as c. Then x is just an integer.
test(a, b, c){
for(x = 0; x < 4; x++){
a[x] = "" + b[x] + c[x];
}
}
and then I would call this function like this:
coordinatesArray = [coordinate1, coordinate2, coordinate3, coordinate4];
test(coordinatesArray, yAxis, xAxis);
What it then should do with whatever array I run the test function with:
coordinatesArray[0] = "" + yAxis[0] + xAxis[0];
coordinatesArray[1] = "" + yAxis[1] + xAxis[1];
coordinatesArray[2] = "" + yAxis[2] + xAxis[2];
coordinatesArray[3] = "" + yAxis[3] + xAxis[3];
And for example coordinatesArray[0] should then represent coordinate1.
So I would create an array to store the variables so I can easily change which variable to target. The problem though, when I run this, a[x] isn't the variable name, instead, it is their values which means this doesn't work. So my question is, is there any way to store the variables' names in an array so I can target them using a function similar to the one I showed? I want to store the names of the variables in an array and then be able to use the name to target the variable so I can change their values.
Arrays in Javascript has only indices not names, that's why you need Object:
yAxis = [10, 10, 9, 9];
xAxis = [4, 4, 5, 5];
coordinatesArray = ['coordinate1', 'coordinate2', 'coordinate3', 'coordinate4'];
function test(a, b, c){
let arrOfObj = [];
for(let i=0; i < a.length; i++){
let obj = {};
obj[a[i]] = [b[i], c[i]];
arrOfObj.push(obj);
}
return arrOfObj;
}
console.log(test(coordinatesArray,yAxis,xAxis));
So this is what you're trying to do...
yAxis = [10, 10, 9, 9];
xAxis = [4, 4, 5, 5];
coordinate1 = "magic";
coordinate2 = "will";
coordinate3 = "happen";
coordinate4 = "here";
function test(a, b, c) {
for(x = 0; x < 4; x++){
window[a[x]] = "" + b[x] + c[x];
}
}
function log(a) {
let output = [];
for(x = 0; x < 4; x++){
output.push(window[a[x]]);
}
console.log(output);
};
coordinatesArray = ["coordinate1", "coordinate2", "coordinate3", "coordinate4"];
log(coordinatesArray);
test(coordinatesArray, xAxis, yAxis);
log(coordinatesArray);
...but the comments at your question are trying to say that you don't need the variables coordinate1, coordinate2 etc, you can just ALWAYS use one array, like this:
yAxis = [10, 10, 9, 9];
xAxis = [4, 4, 5, 5];
coordinatesArray = ["magic", "will", "happen", "here"];
function test(a, b, c) {
for(x = 0; x < 4; x++){
a[x] = "" + b[x] + c[x];
}
}
console.log(coordinatesArray);
test(coordinatesArray, xAxis, yAxis);
console.log(coordinatesArray);
right?
To me it looks like the OP asks for a simple object based key value store. But I might have gotten this wrong.
Thus the answer first puts the focus on how to generate a list of concatenated pairs of x-y coordinates, which in my opinion is the most pragmatic approach ...
const yAxis = [10, 10, 9, 9];
const xAxis = [4, 4, 5, 5];
const coordinatesList = yAxis.map((y, idx) => `${ y }${ xAxis[idx] }`);
console.log('(...coordinatesList) =>', coordinatesList);
.as-console-wrapper { max-height: 100%!important; top: 0; }
If one is not in need of assigning the list's coordinate values, each to a variable-name that could not already be generically created, this list already is a good enough storage.
On the other hand, a destructuring assignment of such a list allows the creation of tailored variables exactly within the scope that is needed (the example code of this approach does also refactor the mapping function from the first provided example) ...
function concatinateCorrespondingBoundArrayItem(partial, idx) {
return [partial, this[idx]].join('');
}
const yAxis = [10, 10, 9, 9];
const xAxis = [4, 4, 5, 5];
const [
foo,
bar,
baz,
biz
] = yAxis.map(concatinateCorrespondingBoundArrayItem, xAxis);
console.log('foo bar baz biz :', foo, bar, baz, biz);
.as-console-wrapper { max-height: 100%!important; top: 0; }
Finally, the storage the OP might have asked for, has to be object/map based. A possible approach could then look similar to this last provided example ...
function createCoordinateRecord(collector, coordinateName, idx) {
collector.storage[coordinateName] = [
collector.yCoordList[idx],
collector.xCoordList[idx]
].join('');
return collector;
}
const yAxis = [10, 10, 9, 9];
const xAxis = [4, 4, 5, 5];
const coordinateNameList = ['foo', 'bar', 'baz', 'biz']
const coordinatesMap = coordinateNameList.reduce(createCoordinateRecord, {
xCoordList: xAxis,
yCoordList: yAxis,
storage: {}
}).storage;
console.log('coordinatesMap :', coordinatesMap);
console.log('coordinatesMap.foo :', coordinatesMap.foo);
console.log('coordinatesMap.bar :', coordinatesMap.bar);
console.log('coordinatesMap[coordinateNameList[2]] :', coordinatesMap[coordinateNameList[2]]);
console.log('coordinatesMap[coordinateNameList[3]] :', coordinatesMap[coordinateNameList[3]]);
console.log('Object.keys(coordinatesMap) :', Object.keys(coordinatesMap));
console.log('Object.values(coordinatesMap) :', Object.values(coordinatesMap));
console.log('Object.entries(coordinatesMap) :', Object.entries(coordinatesMap));
.as-console-wrapper { max-height: 100%!important; top: 0; }
I am stuck with splitting an array in multiple parts, based on pairs and duplicates.
I have this array :
var array = [[24, 17],[45, 17],[17, 24],[38, 31],[31, 38],[17, 45]];
and i need to split it to obtain this :
var array = [[24,17,45],[38,31]];
Does someone have any idea of the right way to do it ?
Any help would be greatly appreciated !
You could take the power of Set and check if the one of the value is already in one set. If not create a new result set with a new set.
var array = [[24, 17], [45, 17], [17, 24], [38, 31], [31, 38], [17, 45]],
result = array
.reduce((r, a) => {
var s = r.find(s => a.some(Set.prototype.has, s));
if (s) {
a.forEach(v => s.add(v));
} else {
r.push(new Set(a));
}
return r;
}, [])
.map(s => Array.from(s));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could use a hashtable that maps a certain mesh to a collision, so you can group them easily:
const array = [[24, 17],[45, 17],[17, 24],[38, 31],[31, 38],[17, 45]];
const result = [], hash = {};
for(const [a, b] of array) {
let group = hash[a] || hash[b] || (arr => (result.push(arr), hash[a] = hash[b] = arr))([]);
if(!group.includes(a)) group.push(a);
if(!group.includes(b)) group.push(b);
}
console.log(result);
You can flatten the array by spreading into Array.concat(), and then reduce the array. Using a helper Set, add a new sub array when a duplicate is detected. Afterwards, filter out the empty arrays:
const array = [[24, 17],[45, 17],[17, 24],[38, 31],[31, 38],[17, 45]];
const helperSet = new Set();
const result = [].concat(...array)
.reduce((r, n) => {
!r[r.length - 1] && r.push([]);
if(!helperSet.has(n)) {
r[r.length - 1].push(n)
helperSet.add(n);
} else {
r.push([]);
};
return r;
}, [])
.filter(({ length }) => length);
console.log(result);
I am looking an elegant way in ES6 to transform this array:
var src = [{x:1,y:'a'},{x:2,y:'b'}];
To this array:
var desc = [[1,2],["a","b"]];
Which contains an array of all the properties and one array for all the values.
For this, i have written this code:
var src = [{x:1,y:'a'},{x:2,y:'b'}];
var prop1 = [];
var prop2 = [];
src.forEach(item => {
prop1.push(item.x)
prop2.push(item.y);
});
var desc = [prop1, prop2];
It works fine but it is quite long, so I am looking for an eventual improvement and a short code.
You name the props order (because the order of keys in object is not guaranteed) and then map over src array by extracting correspondend prop value.
var src = [{x:1,y:'a'},{x:2,y:'b'}]
var props = ['x', 'y'];
var result = props.map(prop => src.map(x => x[prop]))
console.log(result)
You can use .reduce():
let src = [{x: 1, y: 'a'}, {x:2, y: 'b'}];
let result = src.reduce((a, c) => (a[0].push(c.x), a[1].push(c.y), a), [[], []]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Docs:
Array.prototype.reduce()
Array.prototype.push()
Comma Operator
You could iterate the array and then by the keys of the object and switch the outer and inner indices the target element.
var src = [{ x: 1, y: 'a' }, { x: 2, y: 'b' }],
desc = [];
src.forEach(o => Object.keys(o).forEach((k, i) => (desc[i] = desc[i] || []).push(o[k])));
console.log(desc);
My js object:
data_obj = {'p1': 1, 'p2':2, 'p3':3}
my array
data_array = ['p1', 'p3']
Now, I want to filter the object based on the array. Expected result is
fil_obj = {'p1': 1, 'p3':3}
Now then, find the key having a maximum value. Expected result is
p3
Since I have object with thousands of items, I expect a very efficient solution.
Since I'm using d3js for this project, solution based on d3js like d3.max would be great.
You could iterate the wanted properties and return the max key.
var data_obj = { p1: 1, p2: 2, p3: 3},
data_array = ['p1', 'p3'],
result = data_array.reduce(function (r, a, i) {
return !i || data_obj[r] < data_obj[a] ? a : r;
}, undefined);
console.log(result);
I've never used d3, but it seems to me you can get the result pretty efficiently with a single call to .reduce():
var data_obj = {'p1': 1, 'p2':2, 'p3':3};
var data_array = ['p1', 'p3'];
var results = data_array.reduce((r,v)=>{
if (v in data_obj) {
r.data[v] = data_obj[v];
if (data_obj[v] > r.maxVal) {
r.maxKey = v;
r.maxVal = data_obj[v];
}
}
return r;
}, {data:{}, maxKey:null, maxVal:Number.NEGATIVE_INFINITY});
console.log(results);
I have 10 different arrays. Each array has different numbers.
array1 = [1,2,3,4,5]
array2 = [6,7,8,9,10]
...
array 10 = [51,52,53,54]
let's say I pass in 7. Then I want to know which array it is from and want to return array number. So in this case it is going to be 2.
Should I write a switch statement for each array? Appreciate it in javascript.
try:
var arrays = [array1, array2, ..., array10];
for(var i=0; i<arrays.length; ++i) {
if (arrays[i].indexOf(value) != -1) {
console.log('found in array' + (i+1));
}
}
You cannot directly retrieve the name of array.The reason is this variable is only storing a reference to the object.
Instead you can have a key inside the same array which represent its name. Then indexOf can be used to find the array which contain the number , & if it is so, then get the array name
var array1 = [1,2,3,4,5];
array1.name ="array1";
var array2 = [6,7,8,9,10];
array2.name ="array2";
var array10 = [51,52,53,54]
array10.name ="array10";
var parArray = [array1,array2,array10]
function _getArrayName(number){
for(var o=0;o<parArray.length;o++){
var _tem = parArray[o];
if(parArray[o].indexOf(number) !==-1){
console.log(parArray[o].name);
}
}
}
_getArrayName(6) //prints array2
jsfiddle
One fast method should be using hash tables or as i would like to call LUT. Accordingly this job boils down to a single liner as follows;
var arrs = {
arr1 : [1,2,3,4,5],
arr2 : [6,7,8,9,10],
arr3 : [12,14,16,17],
arr4 : [21,23,24,25,27,20],
arr5 : [31,34,35,39],
arr6 : [45,46,44],
arr7 : [58,59],
arr8 : [66,67,69,61],
arr9 : [72,73,75,79,71],
arr0 : [81,85,98,99,90,80]
},
lut = Object.keys(arrs).reduce((p,c) => {arrs[c].forEach(n => p[n]=c); return p},{}),
findar = n => lut[n];
document.write("<pre>" + findar(12) + "</pre>");
One way to do this is have the arrays in an object and iterate over the keys/values. This method doesn't presume the arrays (and therefore their names) are in sequential order.
Note: this will always return a the first match from the function and terminate the search.
var obj = {
array1: [1, 2, 3, 4, 5],
array2: [6, 7, 8, 9, 10],
array3: [51, 52, 53, 54],
array4: [51, 52, 53, 54, 7]
}
function finder(obj, test) {
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
return key.match(/\d+/)[0];
}
}
return false;
}
finder(obj, 7); // '2'
DEMO
If you want to find all instances of a value in all arrays the function needs to be altered slightly.
function finder(obj, test) {
var keys = Object.keys(obj);
var out = [];
for (var i = 0; i < keys.length; i++) {
var key = keys[i];
if (obj[key].indexOf(test) > -1) {
out.push(key.match(/\d+/)[0]);
}
}
return out;
}
finder(obj, 7); // ['2', '4']
DEMO