I currently have the following array set up:
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
What I want to do is iterate through these to bring back the arrays under.
As a test I've tried something like this:
for(t in TicketInfo["t1"])
{
i++;
Write(t.i);
}
But it's obviously not working how I want it to.
Any ideas?
I want to be able to output the arrays like [7, 12, 35,39,41, 43]
Thanks
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
for(var j in TicketInfo )
{
for(var p in TicketInfo[j] )
{
for(var i = 0; i < TicketInfo[j][p].length; i++ )
{
console.log(TicketInfo[j][p][i]);
}
}
}
http://jsfiddle.net/J6rTj/
If you're here from google trying to find a way to do a quick print for debugging, here's a one liner for you:
console.log(myArray.join("\n"))
Example:
var myArray = [[1,2,3],[4,5,6],[7,8,9]];
console.log(myArray.join("\n"));
Output:
1,2,3
4,5,6
7,8,9
Example with proper brackets:
var myArray = [[1,2,3],[4,5,6],[7,8,9]];
console.log("[[" + myArray.join("],\n[") + "]]");
Output:
[[1,2,3],
[4,5,6],
[7,8,9]]
Answer to OP's question:
obj = {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33],
}
var keys = Object.keys(obj);
keys.sort();
console.log(keys);
var listFromObj = []
for (var i = 0; i < keys.length; i++) {
if (obj.hasOwnProperty(keys[i])) listFromObj.push(obj[keys[i]]);
}
console.log("[" + listFromObj.join("]\n[") + "]");
Output:
[7,12,35,39,41,43]
[7,15,20,34,45,48]
[3,7,10,13,22,43]
[2,4,5,23,27,33]
The syntax is TicketInfo["t1"]["1"][0].
That example will give you 7.
TicketInfo["t1"]["1"] will give you the array you're after at the base of your question.
In your code t just represents the key.
Try following code:
var TicketInfo =
{
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
},
t2: {
1: [10, 12, 17,44,48, 49],
2: [13, 15, 17, 18, 32, 39],
3: [16, 17, 20, 45, 48, 49],
4: [6, 16, 18, 21, 32, 40]
}
}
for(t in TicketInfo["t1"])
{
i++;
console.log(TicketInfo["t1"][t]);
}
Do I understand that you want to output entire table in order? Since you use objects on t1/t2 level, you'll have to do extra steps for that.
First, see if you can simply replace objects with real arrays:
var TicketInfoArrays = {
t1: [
[7, 12, 35,39,41, 43],
[7, 15, 20,34,45, 48],
[3, 7, 10, 13, 22, 43],
[2, 4, 5,23,27, 33]
]
}
var t1 = TicketInfoArrays.t1
for(var idx = 0, len = t1.length; idx<len; idx++){
var line = idx+": ["
var nested = t1[idx]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
}
If that's somehow impossible, but you sure that keys in those objects always start at some specific number and go ascending without gaps, you can simply itreate over properties until you hit empty element:
var TicketInfo = {
t1: {
1: [7, 12, 35,39,41, 43],
2: [7, 15, 20,34,45, 48],
3: [3, 7, 10, 13, 22, 43],
4: [2, 4, 5,23,27, 33]
}
}
var t1 = TicketInfo.t1
var idx = 1
var nested
while(nested = t1[idx]){
var line = idx+": ["
var nested = t1[idx]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
idx++
}
Finally, if you can't guarantee even that, you will have to manually collect all keys, sort them and then iterate over this sorted list.
var TicketInfoUnordered = {
t1: {
8: [7, 12, 35,39,41, 43],
20: [7, 15, 20,34,45, 48],
45: [3, 7, 10, 13, 22, 43],
3: [2, 4, 5,23,27, 33]
}
}
var t1 = TicketInfoUnordered.t1
var keys = []
for(key in t1){
if(t1.hasOwnProperty(key)){ keys.push(key) }
}
keys.sort(function(a, b){ return a - b })
for(var idx = 0, len = keys.length; idx<len; idx++){
var line = keys[idx]+": ["
var nested = t1[keys[idx]]
for(var idx2 = 0, len2 = nested.length; idx2<len2; idx2++){
line += ((idx2 > 0 ? ', ':'') + nested[idx2])
}
console.log(line + ']')
}
Related
I've written a a function which takes score as parameter and should return the letter grade.
There are some conditions to be followed while writing the code. ie: return 'A' if 25 < score <= 30 return 'B' if 20 < score <= 25 and so on. So I wanted to do this by omitting a whole lot of if-else's. As I'm new to javascript this is all I could come up with:
// This function takes Nested arrays and a single number,
// which checks its availability in
// the inside array and then return the index of the array
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
// function to get letter grade
function getGrade(score) {
let grade;
var gradeDict = {
'A': [26, 27, 28, 29, 30],
'B': [21, 22, 23, 24, 25],
'C': [16, 17, 18, 19, 20],
'D': [11, 12, 13, 14, 15],
'E': [6, 7, 8, 9, 10],
'F': [0, 1, 2, 3, 4, 5]
}
var keys = Object.keys(gradeDict);
var values = [Object.values(gradeDict)]
grade = keys[my_index(values, score)]
return grade;
}
The first function works fine. It returns the index of nested array. But the main function getGrade happens to return 'Undefined'. Can't think of a better solution than this to reduce a bunch of ugly if-elses.
var question = {
'1st': 'Can anybody help me get this done?',
'2nd': 'Is there any better way to do this?'
}
Is there a better way to write this?
I'd do:
function getLetterGrade(score) {
return ['F', 'F', 'E', 'D', 'C', 'B', 'A'][Math.ceil(score / 5)];
}
(F occurs twice because more scores map to F than to other grades)
It may be a bit cryptic, but is easier to tune should the possible score ever change.
Remove the outer [] array of the Object.values. Object.values already returns values in array.
from
var values = [Object.values(gradeDict)];
to
var values = Object.values(gradeDict);
working example:
function my_index(arr, score) {
for (const [index, elem] of arr.entries()) {
if (elem.includes(score)) {
return index;
}
}
}
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
var keys = Object.keys(gradeDict);
var values = Object.values(gradeDict);
grade = keys[my_index(values, score)];
return grade;
}
console.log(getGrade(5));
console.log(getGrade(25));
Alternate solution
function getGrade(score) {
let grade;
var gradeDict = {
A: [26, 27, 28, 29, 30],
B: [21, 22, 23, 24, 25],
C: [16, 17, 18, 19, 20],
D: [11, 12, 13, 14, 15],
E: [6, 7, 8, 9, 10],
F: [0, 1, 2, 3, 4, 5],
};
for (let key in gradeDict) {
if (gradeDict[key].includes(score)) return key;
}
return "Not found";
}
console.log(getGrade(5));
console.log(getGrade(25));
I like the ceil solution proposed earlier, but here is another general solution in case it's helpful:
function grade(score) {
if (score < 0 || score > 30) throw RangeError(`Score ${score} out of range`);
for (let ii = 5; ii >= 0; ii--) {
if (score > 5*ii) return String.fromCharCode(70 - ii);
}
return 'F';
}
console.log(0, '=>', grade(0)) // F
console.log(4, '=>', grade(4)) // F
console.log(6, '=>', grade(6)) // E
console.log(10, '=>', grade(10)) // E
console.log(27, '=>', grade(27)) // A
console.log(30, '=>', grade(30)) // A
If my Array1 is
Array1 = [1,2,3,4,5,6,7,8,9,10]
the Result should be the same as Combined_Array= [1,2,3,4,5,6,7,8,9,10]
if i got
Array2=[11,12,13,14,15,16,17,18,19,20]
the Resut should be Combined_Array =[1,2,3,4,5,11,12,13,14,15]
and if again i got
Array3=[21,22,23,24,25,26,27,28,19,30]
The Combined_array = [1,2,3,11,12,13,21,22,23,24]
and so on , Doesnt matter how much Array's i want that it should give me a Combined_Array from all the different Array with Fixed Length
Need a Function to make this work .
You could take a closure over the collected arrays and retuen an array of the parts which are difined by the count of arrays.
const
getCombined = (a) => {
const allArrays = [];
return (b => {
allArrays.push(b);
let i = 0,
p = Math.floor(10 / allArrays.length),
result = [];
while (i < allArrays.length) result.push(...allArrays[i++].slice(0, p));
while (result.length < 10) result.push(allArrays[allArrays.length - 1][p++]);
return result;
});
};
var c = [],
add = getCombined(c);
c = add([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
console.log(...c); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
c = add([11, 12, 13, 14, 15, 16, 17, 18, 19, 20]);
console.log(...c); // [1, 2, 3, 4, 5, 11, 12, 13, 14, 15]
c = add([21, 22, 23, 24, 25, 26, 27, 28, 29, 30]);
console.log(...c); // [1, 2, 3, 11, 12, 13, 21, 22, 23, 24]
You need to consider many corner cases (if result array length exceeds given arrays count, if given arrays length differs and so on).
This will work for the simple scenario:
const arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const arr2 = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
const arr3 = [21, 22, 23, 24, 25, 26, 27, 28, 19, 30];
const combineArrays = (arr, length) => {
let elementsCount = Math.floor(length / arr.length);
const result = arr.reduce((acc, el) =>
acc.concat(el.slice(0, elementsCount)), []);
while (result.length < length)
result.push(...arr.pop().slice(elementsCount, ++elementsCount));
return result;
};
const result1 = combineArrays([arr1], 10); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
const result2 = combineArrays([arr1, arr2], 10); // [1, 2, 3, 4, 5, 11, 12, 13, 14, 15]
const result3 = combineArrays([arr1, arr2, arr3], 10); // [1, 2, 3, 11, 12, 13, 21, 22, 23, 24]
I am working through freecodecamp's basic algorithm challenges. The challenge is to return the largest number in an array. Here's the code.
function largestOfFour(arr) {
// You can do this!
let largestWord = [0,0,0,0];
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
if(arr[i][j] > largestWord[i]) {
largestWord[i] = arr[i][j];
}
}
}
return largestWord;
}
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]);
I have passed three of the criteria:
largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]) should return an array.
Passed
largestOfFour([[13, 27, 18, 26], [4, 5, 1, 3], [32, 35, 37, 39], [1000, 1001, 857, 1]]) should return [27, 5, 39, 1001].
Passed
largestOfFour([[4, 9, 1, 3], [13, 35, 18, 26], [32, 35, 97, 39], [1000000, 1001, 857, 1]]) should return [9, 35, 97, 1000000].
All except largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]) should return [25, 48, 21, -3].
Where did I go wrong?
So in your code you went wrong in this block.
if(arr[i][j] > largestWord[i]) {
largestWord[i] = arr[i][j];
}
The thing you forgot was you have a starting value for the largest number which is 0 and you compare array elements with that value. Only a value exceeds 0 going to replace that. So I would suggest just to initialize the array without values and do a check for that
//initialize the array without a value
let largestWord = new Array(4);
for(let i = 0; i < arr.length; i++) {
for(let j = 0; j < arr[i].length; j++) {
//also add a check for initial value
if(arr[i][j] > largestWord[i] || largestWord[i] == undefined) {
largestWord[i] = arr[i][j];
}
}
}
Seems you can do this a lot easier with .map() and Math.max()
function largestOfFour(arr) {
return arr.map(x => Math.max(...x));
}
console.log(largestOfFour([[4, 5, 1, 3], [13, 27, 18, 26], [32, 35, 37, 39], [1000, 1001, 857, 1]]));
console.log(largestOfFour([[17, 23, 25, 12], [25, 7, 34, 48], [4, -10, 18, 21], [-72, -3, -17, -10]]));
Hi i have a problem when code, I want to check an even number in multidimensional array and then change to 'X' if there are even numbers in row or column more than equals to 3 times appear but I change it all to 'X' eventhough it's less than 3. my code like this :
function evenNumbers(numbers){
for(var i = 0; i < numbers.length; i++){
for(var j = 0; j < numbers[i].length; j++){
if(numbers[i][j] % 2 == 0){
numbers[i][j] = 'X'
}
}
}
return numbers
}
console.log(evenNumbers([
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
]));
expected output :
[1, 'X', 'X', 'X', 5],
['X', 17, 'X', 11, 10],
['X', 11, 'X', 'X', 'X'],
['X', 12, 19, 27 , 21],
[''X, 'X', 'X', 'X', 'X']
what I got :
[ [ 1, 'X', 'X', 'X', 5 ],
[ 'X', 17, 'X', 11, 'X' ],
[ 'X', 11, 'X', 'X', 'X' ],
[ 'X', 'X', 19, 27, 21 ],
[ 'X', 'X', 'X', 'X', 'X' ] ]
Thanks, in advance
Help me with no ES6 built-in just regular JS, please. Thanks again
You could use some to make the check, then map
const arr = [
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
];
function xEvens(arr) {
return arr.map(row => {
let i = 0;
let shouldChange = row.some(n => n % 2 === 0 && ++i >= 3);
return shouldChange ? row.map(n => n % 2 === 0 ? 'X' : n) : row;
});
}
console.log(xEvens(arr));
Pre es6 version
var arr = [
[1, 2, 4, 6, 5],
[6, 17, 8, 11, 10],
[8, 11, 10, 18, 16],
[18, 12, 19, 27, 21],
[22, 10, 12, 22, 12]
];
function xEvens(arr) {
return arr.map(function(row) {
var i = 0;
var shouldChange = row.some(function(n) {
return n % 2 === 0 && ++i >= 3;
});
return shouldChange ? row.map(function(n) {
return n % 2 === 0 ? 'X' : n
}) : row;
});
}
console.log(xEvens(arr));
You can try following approach:
Idea:
Loop on array and return an array where X is replaced for even numbers.
Keep a track of count of replacements.
If count matches the threshold, return this new array.
If not, return the original array.
This way you will not need an extra loop just to check the validity for replacement.
function replaceEvensWithCondition(arr, minCount, replaceChar) {
return arr.map(function(row) {
var count = 0;
var updatedArray = row.map(function(n) {
var isEven = n % 2 === 0;
count += +isEven;
return isEven ? replaceChar : n;
});
return count >= minCount ? updatedArray : row
});
}
var arr = [ [1, 2, 4, 6, 5], [6, 17, 8, 11, 10], [8, 11, 10, 18, 16], [18, 12, 19, 27, 21], [22, 10, 12, 22, 12] ];
console.log(replaceEvensWithCondition(arr, 3, 'X'));
jsfiddle with all the data which crashes and doesn't run.
jsfiddle with less data which runs but if you
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
It shows it is undefined.
I have a multi dimensional array in Javascript which runs some calculations for me. This array gets converted to a object literal and then after some data manipulation is changed to a json object and eventually a string. The program works great!
I have to add 310 more lines to the multi dimensional array. When I do I get this error,
index.html:331 Uncaught TypeError: Cannot read property '0' of
undefined
The original array looks like this,
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37]
];
Notice the single digit numbers do not have a 0 in the tens place. But the new data looks like this,
[05, 07, 17, 18, 33, 35],
It does have a 0 in the tens place. I mention this because from aside from it being 310 more lines to the array that is the only difference. I have checked the data 50 times and there is nothing wrong with it.
Would a small difference like that make a difference to cause an error like this? It says the error is getting throws at line 331 in my program,
var obj = {};
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0, j = pastWinners.length; i < j; i++) {
if (obj[pastWinners[g][i]] == undefined) {
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
}
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
var picks = [];
for (var numbs in obj) {
picks.push([numbs, obj[numbs]])
picks.sort(
function(a, b) {
return a[1] - b[1]
}
)
}
picks.reverse();
var topPicks = []
for (var winners = 0; winners < 6; winners++) {
topPicks.push(picks[winners][0]);
}
var weekPicks = topPicks.toString();
console.log(weekPicks);
alert(weekPicks);
Does anyone see any reason this would happen when I add this data in? If it is an issue of the size of the array how can I handle this because I have a few thousand more lines of data to add in.
row 0, col 0
index.html:333 undefined
index.html:332 row 0, col 1
index.html:333 undefined
index.html:332 row 0, col 2
index.html:333 undefined
index.html:332 row 0, col 3
index.html:333 undefined
index.html:332 row 0, col 4
index.html:333 undefined
index.html:332 row 0, col 5
index.html:333 undefined
index.html:332 row 0, col 6
index.html:333 undefined
By adding a console.log(g) of what index you were up to when the error happens, this is actually an issue with your data:
[2, 7, 8, 9, 27, 38],
[9, 12, 17, 24, 26, 41]
[18, 20, 21, 31, 40, 44],
You are missing a comma after the 176th index. https://jsfiddle.net/6h7bedtL/1/
Try to print the array in the console when you get undefined and check your array size in the log.
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0, j = pastWinners.length; i < j; i++) {
if (obj[pastWinners[g][i]] == undefined){
console.log(`row ${g}, col ${i}`);
console.log(obj[pastWinners]);
}
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
I would do it differently:
a. change the second loop...
b. define obj
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37],
];
var obj=[];
for (var g = 0; g < pastWinners.length; g++) {
for (var i = 0; i < pastWinners[g].length; i++) {
if (obj[pastWinners[g][i]]) { //this is line 331
obj[pastWinners[g][i]]++;
} else {
obj[pastWinners[g][i]] = 1;
}
}
}
console.log(obj)
Also you should check for the existence of pastWinners[g] before you loop through it or try to access a child array using
if (pastWinners[g] != null) {
The reason for this is that if pastWinners[g] for some reason is not defined, then your script will attempt to do this:
undefined[i] or get the value of [i] from undefined -- which it cant because undefined is not an array -- which breaks your script
var pastWinners = [
[2, 9, 19, 23, 38, 40],
[17, 25, 31, 35, 38, 43],
[8, 10, 17, 30, 33, 43],
[10, 17, 26, 28, 36, 43],
[14, 20, 25, 28, 34, 41],
[8, 13, 21, 23, 25, 43],
[10, 11, 18, 24, 27, 30],
[21, 22, 23, 26, 33, 39],
[6, 21, 23, 29, 36, 40],
[10, 12, 16, 21, 25, 42],
[1, 11, 20, 27, 34, 37],
];
for (var g = 0; g < pastWinners.length; g++) {
if (pastWinners[g] != null) { // check for valid item
for (var i = 0, j = pastWinners[g].length; i < j; i++) {
if (pastWinners[g][i] != null) {
pastWinners[g][i]++;
} else {
pastWinners[g][i] = 1;
}
}
}
}
console.log(pastWinners);
Possibly
for (var i = 0, j = pastWinners.length; i < j; i++)
should be
for (var i = 0, j = pastWinners[g].length; i < j; i++)
The array items in pastWinners do not have the length of pastwinners :D