Music Box issues - javascript

Trying to push audio files into array. I don't understand why its not working. I've assigned the file to the array and used the push method. When I print out what is in the array it still reads null but has the correct length for the array whats going wrong?
var curr_audio = [];
var j = 0;
for(var i = 0; i < notesParsed.length; i++)
{
if(notesParsed[i] == 'A')
{
curr_audio.push(new Audio("audio.Mp3/GameTone1.mp3"));
}
if(notesParsed[i] == 'B')
{
curr_audio.push(new Audio("audio.Mp3/cartoonRiochet.mp3"));
}
if(notesParsed[i] == 'C')
{
curr_audio.push(new Audio("audio.Mp3/cymbal_crash.mp3"));
}
}
alert(JSON.stringify(curr_audio));

From the MDN docs. You can see that data structures, eg sets are not properly serializable.
console.log(JSON.stringify([new Set([1])]))
It is the same thing with Audio.
If you console.log the result instead you should see that they are actually there.
const audioArray = []
for (let i = 0; i < 5; i++) {
audioArray.push(new Audio())
}
console.log('With stringify', JSON.stringify(audioArray))
console.log('Without stringify', audioArray)

Related

How to delete rows on source right after they were pushed into an array (Sheets)

How to make to make it delete the rows that match a criteria and were pushed into an array?
So far, I got the following, but it gives me out of bounds error:
for (var i = 1; i < values.length; i++) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
On Source sheet, I got headers
I've seen that delete row actually works from bottom to top, but how I can re-reference i rows within that for loop?
Thanks!
Loop backwards:
for (var i = (values.length-1); i > 0; i--) {
if (values[i][0] == productCode) {
data.push([values[i][22],values[i][23],values[i][24],values[i][25]]); //This array is for a certain purpose.
headerData.push(headerValues[i]);//This array is for another certain purpose.
sheet.deleteRow(i+1); //This is the one I'm having trouble with.
}
}
I would try something like that:
let headerData = []
let data = [];
const headerSize = 1;
for (let i = values.length - 1; i > headerSize; i--) {
if (values[i][0] === productCode) {
let row = [values[i][22],values[i][23],values[i][24],values[i][25]]
data = [row, ...data]
headerData = [headerValues[i], ...headerData]
sheet.deleteRow(i+1);
}
}
use destructuring arrays to keep the values in order

Create new array by matching values passed in url using JavaScript

I am building a web application that is primarily using Tableau elements (filters, visualizations, etc.) and the problem I have run into is in passing a large amount (dynamic) of filtered parameters across web pages. I've been trying to work with the JavaScript below, but not having any luck.
function getFilterd()
{
var worksheets = vizFilter.getWorkbook().getActiveSheet().getWorksheets();
var prjArray = window.location.search.substring(1).split(',');
var newArray = [];
//Run through field/filter names
var displayFilters = function (filters) {
for (var i = 0; i < filters.length; i++) {
filterName = filters[i].getFieldName();
//If field/filter name == PRJECT then store selected values in an array
if (filterName == 'PRJECT') {
filterList = []
for (var z = 0; z < filters[i].getAppliedValues().length; z++) {
filterList[z] = filters[i].getAppliedValues()[z].value;
}
//Compare filterList values to prjArray and push to newArray if a match
for (var t = 0; t < filterList.length; t++) {
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
}
}
}
}
}
//Runs through each worksheet in active workbook (optional)
for (var worksheetIndex = 0; worksheetIndex < worksheets.length; worksheetIndex++){
worksheets[worksheetIndex].getFiltersAsync().then(displayFilters);
}
}
So I was finally able to figure this out. The logic below was incorrect as mentioned by Justin in his answer:
//Compare filterList values to prjArray and push to newArray if a match
for (var t = 0; t < filterList.length; t++) {
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
}
In addition, were some syntax errors in the if statement. The following is the revised statement that did return the desired array:
//Compare filterList values to prjArray and push to newArray if a match
newArray = []
for (var t = 0; t < filterList.length; t++){
if (prjArray.indexOf(filterList[t].substring(4)) != -1) {
newArray.push(filterList[t]);
};
}
When you do a split() on window.location.search.substring(1), you return an array. Here, you are comparing a substring against an array, and that is always going to return false.
if (filterList[t].getAppliedValues()[t].value.substring(4) == prjArray) {
newArray.push(filterList[t]);
}
Additionally, you are only putting values into filterList and trying to access them with getAppliedValues is not going to work.
You need to test if the substring is within the array. You can do this using includes() to determine if the array includes the value provided.
if (prjArray.includes(filterList[t].substring(4))) {
newArray.push(filterList[t]);
}
The includes() method is not completely supported by all browsers. If you need backward compatibility,you can do this using indexOf and test is it returns other than -1
if (prjArray.indexOf(filterList[t].substring(4)) !== -1) {
newArray.push(filterList[t]);
}

Matching two arrays with HTML elements

I'm trying to run a function only if the HTML in my two arrays match. Trying to change the arrays toString() changes the HTML in the arrays to "Object HTMLElement" which doesn't work. Using array.outerHTML() comes back with an error same with array.val(). I would rather not do a double for loop but I even tried that and still nothing. This should be pretty simple, what am I missing?
Context: I'm trying to make a Simon Game http://codepen.io/zjmitche/pen/MpWzop?editors=1010
//array content in console
var arrayOne = [section#three.square4, section#one.square4, section#three.square4, section#three.square4]
var arrayTwo = [section#three.square4, section#one.square4, section#three.square4, section#two.square4]
function nextCount() {
if (arrayOne === arrayTwo) {
//do something
{
}
Attempted for loop:
for (var i = 0; i < arrayOne.length; i++) {
for (var j = 0; j < arrayTwo.length; j++) {
if (arrayOne[i] != arrayTwo[j]) {
alert("test")
arraysMatch = false;
}
}
}
Well, for starters, you only need a single loop since if the lengths are different they clearly don't match. Then, use JSON.stringify to compare complex values easily:
arraysMatch = true;
if (arrayOne.length !== arrayTwo.length) {
arraysMatch = false;
} else {
for (var i = 0; i < arrayOne.length; i++) {
// Use JSON.stringify to get deterministic strings of non-primitives
var currVal1 = JSON.stringify(arrayOne[i]);
var currVal2 = JSON.stringigy(arraytwo[i]);
if (currVal1 !== currVal2) {
arraysMatch = false;
break; // No reason to keep going through the loop any more
}
}
}

JS check if the value of object exists

So, I have following js setup:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
Then,
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (NAMES[my_name] !== 185){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}
alert(JSON.stringify(NAMES , null, 4));
Here is a screenshot of the alert:
I hardcoded the number "185" for this example. I need to check if the id of 185 exists, then skip to else. I am not sure how to check it. I tried typeof, undefinedetc. but no luck.
(In other words, I should only have one "185").
Any help? Thanks!
If I understood correctly what you are trying to achieve, you have to iterate over NAMES and check every element. For example, you could do it using [].some javascript function:
if (!NAMES.some(function(v){return v[my_name]})) {
...
} else {
}
If you want to remove duplication you can just use NAMES as an object instead of array like this
var all_names = [185, 185, 181],
NAMES = {};
for (var j = 0; j < all_names.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
NAMES[my_name] = ["sean","sdfsd","sdfsfd"];
}
alert(JSON.stringify(NAMES, null, 4));
First of all I would recommend making a JS Fiddle or CodePen out of this so people can see the code running.
I believe that the issue is that NAMES[my_name] is not doing what you think it is. NAMES is an Array so when you say NAMES[my_name] you are really asking for the ITEM in the array so you are getting the entire object that you create in the INFO function. What you really want is to see if the object has an attribute that matches the value (e.g. "185" from the my_names array).
This is not the prettiest code but it will show you how to do what you really want to do:
var NAMES = [];
function INFO(id,first,middle,last){
var newMap = {};
newMap[id] = [first, middle, last];
return newMap ;
}
all_names = ["185", "186", "185"]
for (var j = 0; j < all_names.length; j++) {
var my_name = all_names[j];
if (NAMES.length == 0) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
} else {
var match = false;
for (var x = 0; x < NAMES.length; x++) {
console.log(NAMES[x][my_name] + ' : ' + my_name);
if(NAMES[x][my_name]) {
match = true;
}
}
if (!match) {
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}
}
}
alert(JSON.stringify(NAMES , null, 4));
Note the if that looks at NAMES[x][my_name] - this is asking if the item at array index 'x' has an attribute of 'my_name' (e.g. "185"). I believe this is really what you are trying to do. As its after midnight I assure you that there is more concise and pretty JS to do this but this should show you the basic issue you have to address.
Try this code using hasOwnProperty method :
for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values
var my_name = all_names[j]; // has "185, 185, 185"
if (!NAMES[my_name].hasOwnProperty("185")){ //Needs to check here
NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd"));
}else{
}
}

json sibling data

(forgive me if I use slightly incorrect language - feel free to constructively correct as needed)
There are a couple posts about getting data from JSON data of siblings in the returned object, but I'm having trouble applying that information to my situation:
I have a bunch of objects that are getting returned as JSON from a REST call and for each object with a node of a certain key:value I need to extract the numeric value of a sibling node of a specific key. For example:
For the following list of objects, I need to add up the numbers in "file_size" for each object with matching "desc" and return that to matching input values on the page.
{"ResultSet":{
Result":[
{
"file_size":"722694",
"desc":"description1",
"format":"GIF"
},
{
"file_size":"19754932",
"desc":"description1",
"format":"JPEG"
},
{
"file_size":"778174",
"desc":"description2",
"format":"GIF"
},
{
"file_size":"244569996",
"desc":"description1",
"format":"PNG"
},
{
"file_size":"466918",
"desc":"description2",
"format":"TIFF"
}
]
}}
You can use the following function:
function findSum(description, array) {
var i = 0;
var sum = 0;
for(i = 0; i < array.length; i++) {
if(array[i]["desc"] == description && array[i].hasOwnProperty("file_size")) {
sum += parseInt(array[i]["file_size"], 10);
}
}
alert(sum);
}
And call it like this:
findSum("description1", ResultSet.Result);
To display an alert with the summation of all "description1" file sizes.
A working JSFiddle is here: http://jsfiddle.net/Q9n2U/.
In response to your updates and comments, here is some new code that creates some divs with the summations for all descriptions. I took out the hasOwnProperty code because you changed your data set, but note that if you have objects in the data array without the file_size property, you must use hasOwnProperty to check for it. You should be able to adjust this for your jQuery .each fairly easily.
var data = {};
var array = ResultSet.Result;
var i = 0;
var currentDesc, currentSize;
var sizeDiv;
var sumItem;
//Sum the sizes for each description
for(i = 0; i < array.length; i++) {
currentDesc = array[i]["desc"];
currentSize = parseInt(array[i]["file_size"], 10);
data[currentDesc] =
typeof data[currentDesc] === "undefined"
? currentSize
: data[currentDesc] + currentSize;
}
//Print the summations to divs on the page
for(sumItem in data) {
if(data.hasOwnProperty(sumItem)) {
sizeDiv = document.createElement("div");
sizeDiv.innerHTML = sumItem + ": " + data[sumItem].toString();
document.body.appendChild(sizeDiv);
}
}
A working JSFiddle is here: http://jsfiddle.net/DxCLu/.
That's an array embedded in an object, so
data.ResultSet.Result[2].file_size
would give you 778174
var sum = {}, result = ResultSet.Result
// Initialize Sum Storage
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] = 0;
}
// Sum the matching file size
for(var i = 0; i < result.length; i++) {
sum[result[i].desc] += parseInt(result[i]["file_size"]
}
After executing above code, you will have a JSON named sum like this
sum = {
"description1": 20477629,
"description2": 1246092
};
An iterate like below should do the job,
var result = data.ResultSet.Result;
var stat = {};
for (var i = 0; i < result.length; i++) {
if (stat.hasOwnProperty(result[i].cat_desc)) {
if (result[i].hasOwnProperty('file_size')) {
stat[result[i].cat_desc] += parseInt(result[i].file_size, 10);
}
} else {
stat[result[i].cat_desc] = parseInt(result[i].file_size, 10);
}
}
DEMO: http://jsfiddle.net/HtrLu/1/

Categories