Why aren't my nested array elements being added together properly? - javascript

Why I am getting this kinda error. But when I am calculating products of them, they seem fine.
//The funtion will add all the values in that array....
function addArrayValues(arr) {
var addition = 0;
for (var i = 0; i < arr.length; i++) {
for (var j = 0; j < arr[i].length; j++) {
addition += arr[i][j];
}
}
return addition;
}
var addition = addArrayValues([[[23], [34], [54]], [[34], [75]], [[75]], [65]]);
console.log(addition);

You don't have an array of arrays - rather, you have an array of arrays of arrays. You need to go 3 levels deep, not just 2:
//The funtion will add all the values in that array....
function addArrayValues(arr){
var addition=0;
for(var i=0;i<arr.length;i++){
for(var j=0;j<arr[i].length;j++){
for (var k = 0; k < arr[i][j].length; k++) {
addition+=arr[i][j][k];
}
}
}
return addition;
}
var addition=addArrayValues([[[23],[34],[54]],[[34],[75]],[[75]],[65]]);
console.log(addition);
Or use .flat instead:
//The funtion will add all the values in that array....
const addArrayValues = arr => arr
.flat(2)
.reduce((a, b) => a + b, 0);
var addition=addArrayValues([[[23],[34],[54]],[[34],[75]],[[75]],[65]]);
console.log(addition);
Your original code is implicitly coercing the 3-deep arrays to strings first, so, eg, iterating over
[[23],[34],[54]]
starts by calculating
[23] + [34] + [54]
so the arrays are turned to strings during the creation of the addition variable.

Related

Js Math.random not random [duplicate]

I tried to get this to work, but the outer loop stops after second iteration, and everything that's after it does not execute(just like it was the end of the script). I want to fill two dimensional array with any character(here i used 'q' as an example)
var A=[[],[]];
for(var i=0;i<12;i++){
for(var j=0;j<81;j++){
A[i][j]='q';
}
}
It didn't work, so i put alert(i+' '+j); to see if it's even executing, and, as i wrote before, it stops after second iteration of outer loop, and then ignores rest of the script.
All I want is to have this array filled with same character in the given range(12 rows, 81 columns in this specific case), so if there's no hope in this method, i'll be glad to see one that works.
This does the job in one line.
var A = Array(12).fill(null).map(()=>Array(81).fill('q'))
This is an array of references and a bad idea as harunurhan commented.
var A = Array(12).fill(Array(81).fill('q'));
The Array.from() method creates a new, shallow-copied Array instance
from an array-like or iterable object.
function createAndFillTwoDArray({
rows,
columns,
defaultValue
}){
return Array.from({ length:rows }, () => (
Array.from({ length:columns }, ()=> defaultValue)
))
}
console.log(createAndFillTwoDArray({rows:3, columns:9, defaultValue: 'q'}))
var A=[[], []];
^ This line declares a two dimensional array of size 1x2. Try this instead:
var A = [];
for (var i = 0; i < 12; i++) {
A[i] = [];
for (var j = 0; j < 81; j++) {
A[i][j] = 'q';
}
}
Since fill() is the most succinct and intuitive, and it works as intended for immutable values, my preference would be an outer from() and an inner fill():
Array.from({length: 12}, _ => new Array(81).fill('q'));
The best approach to fill up 2D array would be like the following
let array2D = [], row = 3, col = 3, fillValue = 1
for (let i = 0; i < row; i++){
let temp = []
for (let j = 0; j < col; j++){
temp[j] = fillValue
}
array2D.push(temp)
}
You need to initialise a new array for i each time the first loop runs, and you don't need to set the layout of the array before you create it (Remove the [], [] inside the declaration of A). Try this:
var A = [];
for (var i = 0; i < 12; i++) {
A[i] = [];
for (var j = 0; j < 81; j++) {
A[i][j] = 'q';
}
}
console.log(A);
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}

Grabbing String From Nested Array Using Nested Loops

I am a totally new to coding and I'm practicing loops and arrays. I created an array with multiple sub arrays that contain pairs of strings. I'm trying to pull out and isolate each string using a nested for loops.
Here is my code:
const pairs = [['Blue', 'Green'],['Red', 'Orange'],['Pink', 'Purple']];
//attempting to use nested arrays to get each string from an array
function getString(arr){
//this loop should grab each array in the list of arrays
for (let i = 0; i < arr.length; i++){
console.log(i , arr[i]);
//this should assign each sub array to a new var to be iterated over
subArr = arr[i];
} for (let j = 0; j < subArr.length; j++){
console.log(j, arr[j]);
}
};
console.log(getString(pairs));
the problem is the output is of the last for loop is : ['Pink', 'Purple'] not each color extracted from the nested loops.
What am I doing wrong here?
Mirii
You should nest the for loops like this:
for (let i = 0; i < arr.length; i++) {
console.log(i, arr[i]);
//this should assign each sub array to a new var to be iterated over
subArr = arr[i];
for (let j = 0; j < subArr.length; j++) {
console.log(j, arr[j]);
}
}
How you have it, they'd run one after the other.
The solution is provided
:
function getString(arr) {
let arrResult = [];
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < arr[i].length; j++) {
arrResult.push(arr[i][j]);
}
}
return arrResult;
}
You need to nest the loops, just like you are nesting the arrays. Also, unless you want to alter i or j, I suggest you use .forEach as it is more simple to work with.
Example:
pairs.forEach((pair, i) => {
pair.forEach((subPair, j) => {
console.log(j, subPair);
});
});
You may also make a variable, push to it within the pair.forEach function, and return it at the end of your root function.
I hope this answers your question, thank you for posting, and have a nice day. ;P
Your loops aren't actually nested: you close the first loop before starting the second one. Because subArr is a global varialbe (no let, const, or var keyword), it's still defined in the second loop, but that's not an ideal way to do things. You also need to log arr[i][j] rather than what you have.
This fixes those issues:
function getString(arr) {
//this loop should grab each array in the list of arrays
for (let i = 0; i < arr.length; i++){
//this should assign each sub array to a new var to be iterated over
let subArr = arr[i];
for (let j = 0; j < subArr.length; j++){
console.log(arr[i][j]);
}
}
};
getString(pairs);
Another issue you have is that you're calling console.log(getString(pairs)), but getString doesn't return anything, it's logging itself. If you want it to return, for example, a newline-delimited string of all the items, you could push items to an array and return them joined with a newline (or whatever character you want):
function getString(arr) {
let ret = []
//this loop should grab each array in the list of arrays
for (let i = 0; i < arr.length; i++){
//this should assign each sub array to a new var to be iterated over
let subArr = arr[i];
for (let j = 0; j < subArr.length; j++){
ret.push(arr[i][j]);
}
}
return ret.join('\n')
};
console.log(getString(pairs));
Nested loops themselves aren't ideal, since they're not as readable as using array methods. Using forEach takes much less code:
function getString (arr) {
arr.forEach(function (subArr) {
console.log(subArr[0])
console.log(subArr[1])
})
}
getString(pairs)
Or, more succinctly, you can use map:
function getString (arr) {
return arr.map(([ a, b ]) => `${a}\n${b}`).join('\n');
}
console.log(getString(pairs))
Even more succinctly, you can do this with [].flat():
const getString = (xs = []) => xs.flat().join('\n')
console.log(getString(pairs))

JavaScript: How to get two elements in a array to equal any given number

My question is:
If I have a array like this,
example:
var myArray = [1,2,4,6,9]
and I want to get the number 15 by getting (adding) the index of 6 and 9.
How do I do that?
I can't make it work and I have tried endlessly... please help.
My attempt:
var list = [1,3,5,7,9];
function sumOfIndex(list , weight) {
weight = [];
for (i = 0; i < list.length; i++) {
for (j = 0; j < list[i].length; j++) {
list.push(weight);
}
}
}
In the array from your example, the index of 6 is [3] and the index of 9 is [4].
Simply add them together and you have 15.
Run the snippet below:
var myArray = [1,2,4,6,9]
console.log(myArray[3] + myArray[4])
I'd go over the array and create a map from the complement of each element to its index:
function findSum (arr, sum) {
const diffs = new Map();
for (let i = 0; i < arr.length; ++i) {
if (diffs.has(arr[i])) {
return [diffs.get(arr[i]), i];
}
diffs.set(sum - arr[i], i);
}
}

How to fill multidimensional array in javascript?

I tried to get this to work, but the outer loop stops after second iteration, and everything that's after it does not execute(just like it was the end of the script). I want to fill two dimensional array with any character(here i used 'q' as an example)
var A=[[],[]];
for(var i=0;i<12;i++){
for(var j=0;j<81;j++){
A[i][j]='q';
}
}
It didn't work, so i put alert(i+' '+j); to see if it's even executing, and, as i wrote before, it stops after second iteration of outer loop, and then ignores rest of the script.
All I want is to have this array filled with same character in the given range(12 rows, 81 columns in this specific case), so if there's no hope in this method, i'll be glad to see one that works.
This does the job in one line.
var A = Array(12).fill(null).map(()=>Array(81).fill('q'))
This is an array of references and a bad idea as harunurhan commented.
var A = Array(12).fill(Array(81).fill('q'));
The Array.from() method creates a new, shallow-copied Array instance
from an array-like or iterable object.
function createAndFillTwoDArray({
rows,
columns,
defaultValue
}){
return Array.from({ length:rows }, () => (
Array.from({ length:columns }, ()=> defaultValue)
))
}
console.log(createAndFillTwoDArray({rows:3, columns:9, defaultValue: 'q'}))
var A=[[], []];
^ This line declares a two dimensional array of size 1x2. Try this instead:
var A = [];
for (var i = 0; i < 12; i++) {
A[i] = [];
for (var j = 0; j < 81; j++) {
A[i][j] = 'q';
}
}
Since fill() is the most succinct and intuitive, and it works as intended for immutable values, my preference would be an outer from() and an inner fill():
Array.from({length: 12}, _ => new Array(81).fill('q'));
The best approach to fill up 2D array would be like the following
let array2D = [], row = 3, col = 3, fillValue = 1
for (let i = 0; i < row; i++){
let temp = []
for (let j = 0; j < col; j++){
temp[j] = fillValue
}
array2D.push(temp)
}
You need to initialise a new array for i each time the first loop runs, and you don't need to set the layout of the array before you create it (Remove the [], [] inside the declaration of A). Try this:
var A = [];
for (var i = 0; i < 12; i++) {
A[i] = [];
for (var j = 0; j < 81; j++) {
A[i][j] = 'q';
}
}
console.log(A);
.as-console-wrapper {
max-height: 100% !important;
top: 0;
}

Fastest way to join two Javascript/JSON Objects by ID

Assuming I have two Javascript Objects (they have a JSON structure, but are created with JSON.parse()). All entries have a unique ID with which the entries from both objects can be matched.
What would be the fastest way to join both objects (native javascript).
The first thing that comes into my mind would be a nested for in loop.
for(var i in firstJson) {
for(var j in secondJson) {
if(firstJson[i].id === secondJson[j].id) {
// join them
}
}
}
Is there a faster way?
More efficient way would be to create an index out of one of them:
var index = {};
for (var j in secondJson) {
var obj = secondJson[j];
index[obj.id] = obj;
};
for (var i in firstJson) {
var firstObj = firstJson[i];
var match = index[firstObj.id];
if (match) {
// do the stuff
}
};
This is O(n+m) instead of O(n*m) for nested loops. At the cost of O(m) memory of course.
If both lists are not already sorted you could first sort them by id, then do the comparison and saving the position of the last found object, starting from the last found if nothing was found.
(I do believe that the solution from freakish is faster, but this has no extra memory consumption)
This should be on the order O(nlog(n)+mlog(m)+m)
first.Sort();
second.Sort();
int idx = 0;
int lastIdx = 0;
for (int i = 0; i < first.Count; i++) {
for (int j = idx; j < second.Count; j++)
{
if (first[i] == second[j])
{
Console.WriteLine("equal " + first[i]);
idx = j + 1;
lastIdx = idx;
break;
}
}
if (idx == second.Count)
idx = lastIdx;
}

Categories