Looking for general advice on approaches here. Description and pseudocode below:
Array1 has 100 objects type integer
Array2 has 100 objects type integer
Create Array 3 10,000 objects summing the two arrays
Array3.1 = Array1.[Field1] from 1 to 100 + Array2.1.[Field1]
Array3.2 = Array1.[Field1] from 1 to 100 + Array2.2.[Field1]
Array3.3 = Array1.[Field1] from 1 to 100 + Array2.3.[Field1]
……
Array3.100 = Array1.[Field1] from 1 to 100 + Array2.100.[Field1]
Challenges:
Not sure how to easily reference the field within an object in the array. I can pull up the object line but this returns the entire object whereas I only want to pull one field. This would be helpful beyond this particular question.
Not sure about the best method to create the new array, whether it should be a loop or something else.
Further background
The final objective will be to create an output that compares the sum of the specific field for every pair within the two arrays to find and then rank them from best to worst.
It's not that difficult.
Every entry in the resulting array is just the 2nd array with the value at the current index of the first array added to it.
const a1 = [0, 5, 10, 15, 20];
const a2 = [0, 2, 4, 6, 8];
const result = a1.map(x => a2.map(y => x + y));
console.log(result);
If you don't want the resulting array to nested, use flatMap:
const a1 = [0, 5, 10, 15, 20];
const a2 = [0, 2, 4, 6, 8];
const result = a1.flatMap(x => a2.map(y => x + y));
console.log(result);
How do I print out the filtered elements from the array?
I tried console.log('randomNumbers/smallNumbers');
But they didn't work.
Please advise, much thanks!
const randomNumbers = [375, 200, 3.14, 7, 13, 852];
const smallNumbers = randomNumbers.filter(num => {
return num < 250;
});
It's not the logging you have troubles with - but Array.filter function. You seem to think it somehow consumes the whole array at once, hence attempt to use length and name the argument the same way as the original array.
What happens instead is that the function you pass in randomNumbers.filter (as its parameter) is called once per each element of that array, taking this element as its first argument.
If result of the function's call for this element is truthy, the element will stay in the result of .filter. If falsy, it gets discarded.
So it can written as simple as this:
const randomNumbers = [375, 200, 3.14, 7, 13, 852];
const smallNumbers = randomNumbers.filter(number => number < 250);
// log the resulting array
console.log(smallNumbers);
// log the small numbers' ratio
console.log((smallNumbers.length / randomNumbers.length).toFixed(2));
const randomNumbers = [375, 200, 3.14, 7, 13, 852];
const smallNumbers = randomNumbers.filter(number => number < 250);
// log the resulting array
console.log(smallNumbers);
// log the small numbers' ratio
console.log((smallNumbers.length / randomNumbers.length).toFixed(2));
I have a function that needs to take an array from each in a group of documents, and sum each position in each array with it's index 'partner' at the [n]th position.
The arrays look something like this......
[300, 230, 45, 0, 0, 0]
[200, 100, 0, 0, 0, 0]
[2, 1, 0, 0, 0, 0]
...
From which I would want to return [502, 331, 45, 0, 0, 0]. Using this question which is asking almost the same thing, I copied a reduce function, so my function now looks like this...
this.projects.forEach(function (project) {
let arrays = project.yearsTotal
result = arrays.reduce(function (r, a) {
a.forEach(function (b, i) {
r[i] = (r[i] || 0) + b;
});
return r
}, []);
})
However, this tells me that 'a.forEach is not a function', I must admit that I'm not sure exactly what the reduce function is doing, but I think perhaps that it isn't working because my arrays are not an array of arrays, they exist separately.
Javascript tells me they are objects, not arrays, but I'm not sure that is significant. Please could someone tell me how to do this?
The difference with the question you linked seems to be your numeric data, that is stored inside array of objects (in property yearsTotal) - and not in array of arrays of numbers.
If that's the case, you can just create another array storing only the values you need:
const projectYearsTotal = this.projects.map(p => p.yearsTotal);
... and then you can proceed with reduce-forEach-ing it.
Your current solution tries to 'zip-sum' the array of numbers (value of 'yearsTotal' of each individual project), not array of arrays of numbers. Hence forEach is not a function error.
This question already has answers here:
Create an array with random values
(24 answers)
Closed 3 years ago.
This is more like a silly question but I have to ask it.
It is a good practice to call an array function like map without arguments?
Let's say I already have an array 'x' on my code with a specified length and I want to make another array with the same length but with different content.
For example:
function generateRandomContent() { ... }
const x = [1, 2, 3, 4, 5]
const y = x.map(() => generateRandomContent())
// or
const z = Array(x.length).fill().map(() => { ... })
Of course I could pass an argument and never use it, but it is there a good way and a bad way to do it?
You should not use .map here. A mapping operation is when you take some input and generate a new output. So you have a relation that looks like this x -> y for a single element, then you apply it to the entire array to generate a new array using the same mapping rule:
const input = [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100];
//mapping relationship
const toCharacter = x => String.fromCharCode(x);
const result = input.map(toCharacter);
console.log(result.join(''))
If you just want to create a new array based on the length of the original but with totally unrelated content, then you are better off to use Array.from which can create an array with a given size and takes a second argument that will fill it with content:
function generateRandomContent() {
return Math.floor(Math.random() * 100);
}
const x = [1, 2, 3, 4, 5]
const y = Array.from({length: x.length}, () => generateRandomContent());
//or just pass the function reference
const z = Array.from({length: x.length}, generateRandomContent);
console.log(y);
console.log(z);
I have two arrays, one with x coordinates and one with y coordinates. I need to create a new array of arrays that group the coordinates.
yCord = [30, 29, 31, 32];
xCord = [0, 1, 2 ,3];
Here is what I had.
var cordPairs = {};
xCord.forEach((key, i) => cordPairs[key] = yCord[i]);
But that pairs the values in an object, I need an array now.
{0: 30, 1: 29, 2: 31, 3: 32}
Desired result:
cordPairs = [[0, 30], [1, 29], [2, 31], [3, 32]]
You need the data in array format so this should work:
const yCord = [30, 29, 31, 32];
const xCord = [0, 1, 2 ,3];
const coords = xCord.map((el, index)=> [el, yCord[index]]);
console.log(coords);
You could take the x and y values in an array and transpose this array.
const
transpose = (r, a) => a.map((v, i) => [...(r[i] || []), v]),
yCord = [30, 29, 31, 32],
xCord = [0, 1, 2 ,3],
result = [xCord, yCord].reduce(transpose, []);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
The other answers are great - but...
This may actually be a situation where, instead of creating a method that can perform the process, you would actually want to create a new Constructor function that will return an object with the innate ability to iterate how you want.
function CoordinateArray(x, y) {
if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
let i = 0;
return {
y,
x,
[Symbol.iterator]: function*() {
while (i < this.y.length) {
yield [this.x[i], this.y[i]];
i++;
}
}
}
}
A functioning code example:
let yCord = [30, 29, 31, 32],
xCord = [0, 1, 2, 3];
function CoordinateArray(x, y) {
if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
let i = 0;
return {
x,
y,
length: x.length,
[Symbol.iterator]: function*() {
while (i < y.length) {
yield [this.x[i], this.y[i]];
i++;
}
}
};
}
let coords = new CoordinateArray(xCord, yCord);
console.log([...coords]);
Why would you do it this way?
When utilizing something in a coordinate system it's likely that the functionality of looping over coordinates is a commonality within your code. A.e. It happens more than once, and if it needs to be extended, the functionality may be needed again.
Creating a Constructor for this purpose allows you to create code that lends itself to higher clarity and concision.
It also allows for greater innate control over how you code.
What do I mean by that?
Creating a method/function that simply iterates over the two Arrays once and returns a bundled coordinate Array is well and good - but let's say that somewhere down the line you simply need to adjust all the x values. With a normal function you would either need to write conditions, or perform the function and, afterwards, perform additional work to get the results you want. A.e.:
getCoordinateArray(xCord, yCord) //perform a lot of work
.map(([x,y]) => [x*2,y]); //perform more work
Whereas if you provide yourself with a Constructor with innate iteration mechanics, you could save yourself the hassle while providing more iteration options:
let coords = CoordinateArray(xCord, yCord); //initial work
coords.x = coords.x.map(i=>i*2); //minimal work
It may not be plain to see, but by doing it the Constructor way, you're adjusting the Object as minimally as possible while still maintaining a functional paradigm. You don't worry about the total results, you only adjust what you need to and the outcome will be as expected. Furthermore, it's crystal clear what you're adjusting in the second example coords.x, whereas in the first it's more of a jumble.
To extend on this as well, you can also abstract away simple mechanics as the above to make your intentions even more clear. Simply add on a method to your Constructor:
function CoordinateArray(x, y) {
return {
...
//new method
move: function(s, c = s.split("")[0]) { this[c] = this[c].map(new Function(c,"return" + s)) },
...
}
}
And the above will become this instead:
let coords = new CoordinateArray(xCord, yCord); // initial work
coords.move("x*2"); // minimal, clear, work.
let yCord = [30, 29, 31, 32],
xCord = [0, 1, 2, 3];
function CoordinateArray(x, y) {
if (y.length != x.length) return Error("CoordinateArray: Incorrect Array Bounds");
let i = 0;
return {
x,
y,
move: function(s, [c,] = s.split("")) { this[c] = this[c].map(new Function(c,`return ${s};`)) },
length: x.length,
[Symbol.iterator]: function*() {
while (i < y.length) {
yield [this.x[i], this.y[i]];
i++;
}
}
};
}
let coords = new CoordinateArray(xCord, yCord);
coords.move("x*2");
console.log([...coords]);
Which, I think anyone will say, is much easier to read - but more importantly with that readability it isn't costing you anything. Even though there is no assignment to coords.x, it isn't mutating your data. Normally with operations you'll see things like x = x.map(); at each step, which does showcase immutability, but it's redundant and obfuscatory when it needn't be.
Yes, a simple function as provided by the other answers may be all you need - but if you are performing coordinate manipulation often in your code, I would urge you to consider alternative routes other than stacking multiple functions. A Constructor would allow you to keep what you need with the benefit of extreme clarity and flexibility with your data and methods, and minimal impact on Scope.
All this being said...
Your use case will decide the best option!
Again, the other answers are perfectly valid ( in fact, a few of the other people who answered I purposely follow because they are very knowledgeable and inspiring) - I only offer this answer to provide more insight into operating with things like coordinate systems. I've written many apps, components, etc, that have utilized them and I've put a lot of time into the process of making them clear and effective for myself as well as others!
Hope this helped! Happy Coding!
Iterate the index of the two arrays, Package the pairs in a javascript array and pus to make an structure of them:
yCord = [30, 29, 31, 32];
xCord = [0, 1, 2 ,3];
var cordPairs = [];
for(var i = 0; i < xCord.length; i++)
{
cordPairs.push([xCord[i], yCord[i]]);
}
Long story short, you want to zip those arrays. With libraries like lodash, it's as simple as
cordPairs = _.zip(xCord, yCord);