I have a 3x3 array:
var my_array = [[0,1,2],
[3,4,5],
[6,7,8]];
and want to get the first 2x2 block of it (or any other 2x2 block):
[[0,1],
[3,4]]
with numpy I would have written:
my_array = np.arange(9).reshape((3,3))
my_array[:2, :2]
to get the correct result.
I tried in javascript:
my_array.slice(0, 2).slice(0, 2);
but the second slice affects the first dimension, doing nothing.
Am I doomed to use for loop or is there some new ES6 syntax that would make my life simpler?
Could use a combination of Array.slice and Array.map:
const input = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
const result = input.slice(0, 2).map(arr => arr.slice(0, 2));
console.log(result);
You can use .map() and .slice() methods:
var my_array = [[0,1,2],
[3,4,5],
[6,7,8]];
var result = my_array.slice(0, 2).map(a => a.slice(0, 2));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could take objects for the indices and for the length of the wanted sub arrays.. Then slice and map the sliced sub arrays.
var array = [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
length = { x: 2, y: 2 },
indices = { i: 0, j: 0 },
result = array.slice(indices.i, indices.i + length.x).map(a => a.slice(indices.j, indices.j + length.y));
console.log(result);
It dont seems to a 3x# array , it is just array of arrays.
You can first use slice to get an array of only first two elements that is
[[0, 1, 2],[3, 4, 5]]
then use reduce to return a new array & inside it get only the first two values
var my_array = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
let x = my_array.slice(0, 2).reduce(function(acc, curr) {
acc.push(curr.slice(0, 2))
return acc;
}, [])
console.log(x)
const input = [
[0, 1, 2],
[3, 4, 5],
[6, 7, 8]
];
let result =[]
input.forEach(([a, b], index) => {if(index < 2) result.push([a, b])})
console.log(result);
If you are going to work a lot with matrices, then you should check out math.js.
Try the following:
var my_array = [[0,1,2],
[3,4,5],
[6,7,8]];
var matrix = math.matrix(my_array);
var subset = matrix.subset(math.index([0, 1], [0, 1]));
Working example.
Related
Given an array of arrays, I want to get the averages of each subarray, and then output which subarrays have the same average. The output will not repeat the subarrays, but just the indices where they occur in the input array.
So for this input:
[
[3, 3, 4, 2], // index 0: average = 3
[4, 4], // index 1: average = 4
[4, 0, 3, 3], // index 2: average = 2.5
[2, 3], // index 3: average = 2.5
[3, 3, 3], // index 4: average = 3
];
The expected output is:
[[0, 4], [1], [2, 3]]
...because the subarrays at indices 0 and 4 have the same average, while the subarray at index 1 has an average that is not shared by another subarray, and finally the subarrays at indices 2 and 3 have the same average.
I completed the function as we see below, and the averages are calculated correctly, but I can't get the values of the object sorted with keys in distinct arrays...
function solution(a) {
let b = [];
let entier = {};
a.filter((elt, cle) => {
let s = a[cle].reduce((prevalue, curvalue) => prevalue + curvalue, 0);
b[cle] = s / a[cle].length;
//console.log(s/a[cle].length)
entier[cle] = s / a[cle].length;
});
console.log(entier);
let arrNew = Object.entries(entier);
console.log(arrNew);
}
let a = [
[3, 3, 4, 2],
[4, 4],
[4, 0, 3, 3],
[2, 3],
[3, 3, 3],
];
solution(a); // [[0, 4], [1], [2, 3]]
How can I make my code work?
With this:
entier[cle] = s / a[cle].length;
...you are assigning the average as a value associated with the current index as the key. But you need the opposite. You'll want to group by the average, so that must be the key, and the index must be the value (but as an array).
So change that to:
(entier["x" + (s / a[cle].length)] ??= []).push(cle);
The "x" is to ensure that the key is not an integer as then different rules apply for the ordering of that key in the object. By prepending this "x", we ensure that keys are ordered in the order they are created.
The ??= assignment ensures that the property is initialised as an array when it didn't exist yet.
The second correction is here: Object.entries should be Object.values as you are no longer interested in those "x" keys.
function solution(a) {
let entier = {};
a.filter((elt, cle) => {
let s = a[cle].reduce((prevalue, curvalue) => prevalue + curvalue, 0);
(entier["x" + (s / a[cle].length)] ??= []).push(cle);
});
let arrNew = Object.values(entier);
console.log(arrNew);
}
let a = [
[3, 3, 4, 2], // 0: 3
[4, 4], // 1: 4
[4, 0, 3, 3], // 2: 2.5
[2, 3], // 3: 2.5
[3, 3, 3], // 4: 3
];
solution(a); // [[0, 4], [1], [2, 3]]
I have an array of arrays:
var arr = [
[0, 3, 3],
[0, 4, 3],
[1, 3, 4],
[1, 4, 4]
];
I want to create a new array that combines the contents of each index of the inner arrays. For example, the first elements at index 0 of each of the inner arrays are 0, 0, 1, and 1. I want to create a new array that combines those elements so that I end up with [0, 1] (I don't want duplicates in the new array). The next "column" is 3, 4, 3, and 4. So I'd want an array of [3, 4].
The end result I want is
[
[0, 1],
[3, 4],
[3, 4]
]
I can't quite figure out how to do this.
May not be the most efficient, but does meet you cryptic requirements.
var arr = [
[0, 3, 3],
[0, 4, 3],
[1, 3, 4],
[1, 4, 4]
];
const unique = (myArray) => [...new Set(myArray)];
let x, y,
tarr = [], // temp array
farr = []; // final array
for (x=0; x<arr.length; x++) {
tarr.length = 0;
for (y=0; y<arr[x].length; y++) {
tarr.push(arr[y][x])
}
farr.push( unique(tarr) );
}
console.log(farr.join('\n'));
Here another solution.
const result = (arr) => {
let index = 0;
const min = Math.min(...arr.map(r => r.length)) // get min length
const grid = [];
while (index < min) { // loop with min
let s = new Set(); // using set to keep unique values
arr.forEach(r => s.add(r[index])); // pick value
grid.push([...s]); // get array from set
index++;
}
return grid
}
const array = [ [0, 3, 3], [0, 4, 3], [1, 3, 4], [1, 4, 4] ];
console.log(result(array))
I have a data stream which continuously needs to update an array. The array itself is always bigger than the stream which is coming in. This would mean that I have to concat the buffer to the array and shift everything. However, concatenation is slow so I was wondering if there is a fast way of doing this?
Example:
var array = [1,2,3,4,5,6];
var stream = [7,8,9];
array = magicalFunction(array,stream); // outputs [4,5,6,7,8,9]
The array function is used for plotting with ChartJS. It's a rolling plot so as data comes in (it comes in chunks) I have to update the chart by shifting the entire data set.
You could use spread syntax .... But if that is faster than concat ...?
var magicalFunction = (a, s) => [...a.slice(s.length - a.length), ...s],
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
With Array.concat
var magicalFunction = (a, s) => a.slice(s.length - a.length).concat(s);
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
With Array.unshift
var magicalFunction = (a, s) => (s.unshift(...a.slice(s.length - a.length)), s);
array = [1, 2, 3, 4, 5, 6],
stream = [7, 8, 9];
array = magicalFunction(array,stream);
console.log(array);
You can apply a .push:
array.push.apply(array, stream);
or in ES2015 you can use the triple dots:
array.push(...stream)
How about a Spread
var stream = [7,8,9];
var array = [1,2,3,4,5,6, ...stream];
Maybe it's late to answer but you could do this with ES6 like this:
let array = [1, 2, 3, 4, 5, 6];
let stream = [7, 8, 9, 1];
const mergedArray = [...array, ...stream]
// fetch only distinct values
const distinctMergedArray = Array.from(new Set(mergedArray))
let array = [1, 2, 3, 4, 5, 6];
let stream = [7, 8, 9, 1];
//set to get distinct value and spread operator to merge two arrays
const resultArray = new Set([...array, ...stream])
I've got an array such as:
var foo = [1, 2, 3, 4, 5];
and I would like to map it to:
var bar = [[1,2], [2,3], [3,4], [4,5], [5,1]];
I do not need to handle scenarios where the length of foo is 0 or 1.
My naive approach is:
var foo = [1, 2, 3, 4, 5];
var bar = _.map(foo, function(value, index) {
return index < foo.length - 1 ? [value, foo[index + 1]] : [value, foo[0]];
});
console.log(bar);
<script src="https://cdn.jsdelivr.net/lodash/3.10.1/lodash.js"></script>
I'm wondering if there's a more clear way to express this mapping.
Using plain simple lodash. First drop the first element from the array, append it, and then zip it with the original array:
var a = [1,2,3,4,5]
var b = _.zip(a, _.concat(_.drop(a), a[0]))
The result:
console.log(b)
[[1, 2], [2, 3], [3, 4], [4, 5], [5, 1]]
_.nth
Gets the element at index n of array. If n is negative, the nth element from the end is returned.
just get sibling in reverse order
var bar = _.map(foo, function(val, index) {
return [val, _.nth(foo, (index + 1) - foo.length)];
});
I am not sure how to use this to remove duplicate arrays from the main array. so consider the following:
var arr = [
[0, 1],
[0, 1],
[2, 1],
];
The resulting array should look like:
var arr = [
[0, 1],
[2, 1],
];
The documentation makes sense for a single array of elements but not a 2d array.
Ideas?
Update, One small issue with some solutions:
The array to be turned unique might have:
var arr = [
[0, 1]
[0, 2]
[0, 3]
[0, 1]
[2, 1]
]
the array in side the array should have all value compared, so in the above example, it should spit out:
var arr = [
[0, 1]
[0, 2]
[0, 3]
[2, 1]
]
The duplicate being [0, 1]
The easiest way would probably be to use uniq method and then convert the inner arrays to some string representation, JSON.stringify should be good enough solution.
var arr = [[0, 1], [0, 2], [0, 3], [0, 1], [2, 1]]
_.uniq(arr, function(item) {
return JSON.stringify(item);
});
// [[0,1], [0,2], [0,3], [2,1]]
You would use the .uniq function in lodash:
var arr = [
[0, 1],
[0, 1],
[2, 1],
]
var uniqueList = _.uniq(arr, function(item, key, a) {
return item.a;
});
The resulting array will look like:
//var arr = [Object: [0, 1], Object: [2, 1]];
Sure, casting to JSON works, but it feels like we might be wasting resources. I'm using the following Lodash-code in Node.js:
const _ = require("lodash");
var arr = [
[0, 1],
[0, 1],
[2, 1],
];
var uni = _.uniqWith(arr, _.isEqual);
console.log(uni);
Works like a charm, check the Repl here. More on uniqWith at the Lodash docs.
It doesn't use lodash, not optimized I agree :
//remove duplicate array of array of arrays
Array.prototype.uniqueArray = function() {
var uniqObj = {};
this.forEach(function (item) {
uniqObj[JSON.stringify(item)] = 1;
});
var uniqArray = [];
for(var key in uniqObj) {
if (uniqObj.hasOwnProperty(key)) {
uniqArray.push(JSON.parse(key))
}
}
return uniqArray;
};