Dynamic Array Value Count - javascript

Similar to this question - Array value count javascript
How would I go about doing this, except with dynamic values?
var counts = []
var dates= [ "28/05/2013", "27/05/2013", "28/05/2013", "26/05/2013", "28/05/2013" ];
How would I get a count of the duplicated array values? So how many 28/05/2013 etc. The dates are all dynamic, so I can't just search for set values. I just can't get my head around how I would do this.
I may just scrap this idea, and get the value count from the last 10 days or something... but this may come in handy later(if it is even possible to do this).

This will do it:
var counts = {};
for (var i=0; i<dates.length; i++)
if (dates[i] in counts)
counts[dates[i]]++;
else
counts[dates[i]] = 1;
The result will be
> counts
{
"28/05/2013": 3,
"27/05/2013": 1,
"26/05/2013": 1
}

Make counts an object to perform duplicate detection in constant time.
var counts = {}
for (var i = 0; i < dates.length; i++) {
var date = dates[i];
if (counts[date] === undefined) {
counts[date] = 0;
}
counts[date] += 1;
}
console.log(counts);

Try like this
Updated
var dates= [ "28/05/2013", "27/05/2013", "28/05/2013", "26/05/2013", "28/05/2013" ];
var findStr = "28/05/2013";
var indexs = dates.indexOf(findStr,0),count=0;
for (var i=0;i< dates.length;i++){
if (indexs >= 0){
indexs = dates.indexOf(findStr,indexs + 1);
count++;
}
}
alert(count);
See Demo

Related

.join is not a function

Newer to coding and javascript and I am trying a codewars challenge. I setup an array to repeat a letter at certain indexes of my newArray based on a loop. For example if input was: cwAt expected output should be: C-Ww-Aaa-Tttt.
Been stuck on this for several hours (and have slept on it). I get error code:
newArray.join is not a function
when I try to run this and not sure what I can do to fix this problem. I feel its something simple and I just need to learn why this is happening.
function accum(s) {
let mumble = s.split('');
for (i = 0; i < mumble.length; i++) {
let newArray = [mumble[i].toUpperCase(), ''];
for (j = i; j > 0; j--) {
newArray = newArray.push(mumble[i]);
};
// Merge the new array into a string and set it at the mumble index required
mumble[i] = newArray.join('');
};
//Return new mumble with - as spaces between elements
return mumble.join('-');
}
console.log(accum('cwAt'));
Change newArray = newArray.push(mumble[i]); to newArray.push(mumble[i]);
push returns new length of the array.
You are storing a number in newArray. Try replace the 4 line with:
let newArray[i] = [mumble[i].toUpperCase(), ''];
and the 5 line :
for (j = 0; j < 0; j++) {
and the 6:
newArray[j] = newArray.push(mumble[i]);

Google Apps Script: Comparing Arrays for Unique Values

I'm working from the solution provided HERE to compare two arrays. The example provided returns values found in both arrays to Array1 (same) and values only found on one or the other two Array2 (diff).
ISSUE: When I apply it to my own script, valuesDATA returns nothing and valuesCheckSeeding returns ALL values from both arrays
DESIRED RESULT: I have two arrays that I'd either like to create a third out of, or only select values from the first array, valuesDATA which are NOT present in the second, valuesCheckSeeding. Using the solution above, I was trying to have all values not found in valuesCheckSeeding AND valuesDATA pushed to valuesDATA.
SAMPLE OF valuesDATA: "U09 F
Harford FC Hill/Healey - A
MD
CMSA Girls Saturday U09 A/B North
Premier - Top
TID0118"
What am I doing wrong? I tinkered with changing matchfound==false and matchfound=true in the loop, but that still didn't give me the desired result.
MOST RELEVANT SNIPPET
var matchfound = false;
for (var i = 0; i < valuesDATA.length; i++) {
matchfound=false;
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i] == valuesCheckSeeding[j]) {
valuesCheckSeeding.splice(j, 1);
matchfound=true;
continue;
}
}
if (matchfound==false) {
valuesCheckSeeding.push(valuesDATA[i]);
valuesDATA.splice(i, 1);
i=i-1;
}
}
WORKIG SCRIPT EDITED FROM COMMENTS/ANSWERS BELOW
//UPDATE SEEDING SHEET
function updateSeedingSheet() {
var today = Utilities.formatDate(new Date(),Session.getScriptTimeZone(), "MM/dd/yyyy hh:mm a");
//INPUT SHEET INFO
var inputCurrentRow = 4;
var inputCurrentColumn = 20;
var inputNumRows = 1000;
var inputNumColumns =1;
var ssInput = SpreadsheetApp.openById('1Wzg2BklQb6sOZzeC0OEvQ7s7gIQ07sXygEtC0CSGOh4');
var sheetDATA = ssInput.getSheetByName('DATAREF');
var rangeDATA = sheetDATA.getRange(inputCurrentRow, inputCurrentColumn, inputNumRows, inputNumColumns);
var valuesDATA = rangeDATA.getValues();
//SEEDING SHEET INFO
var seedingCurrentRow = 4;
var seedingCurrentColumn = 1;
var seedingNumRows = 1000;
var seedingNumColumns = 1;
var ssSeeding = SpreadsheetApp.openById('1DuCHeZ3zba-nHq-7vYTrylncPGqcA1J9jNyW9DaS3mU');
var sheetSeeding = ssSeeding.getSheetByName('Seeding');
var rangeCheckSeeding = sheetSeeding.getRange(4, 102, 1000, 1);
var columnToClear = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, seedingNumRows, seedingNumColumns);
var valuesCheckSeeding = rangeCheckSeeding.getValues();
//METHOD TO FILTER
valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);
Logger.log(filteredArr.length);
var rangeSeeding = sheetSeeding.getRange(seedingCurrentRow, seedingCurrentColumn, filteredArr.length, seedingNumColumns);
sheetSeeding.getRange('A1').setValue(today);
columnToClear.clearContent();
rangeSeeding.setValues(filteredArr);
/*
//ALTERNATIVE METHOD USING LOOPS
for (var i = 0; i < valuesDATA.length; i++) {
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
valuesDATA.splice(i, 1);
i--; //account for the splice
break; //go to next i iteration of loop
}
}
}
Logger.log("VALUES DATA:" + valuesDATA);
Logger.log("VALUES CHECK SEEDING: " + valuesCheckSeeding);
//sheetSeeding.getRange('A1').setValue(today);
//rangeSeeding.clearContent();
//rangeSeeding.setValues(valuesDATA); //INCORRECT RANGE HEIGHT, WAS 71 BUT SHOULD BE 1000 - Is splice affecting this?
*/
}//END FUNCTION
V8(ES2016 update):
You can use newer and efficient set class
const array1 = [[1],[2],[3]],
array2 = [[1],[3],[4]],
set = new Set(array2.flat())
console.info(array1.filter(e => !set.has(e[0])))
//expected output [[2]]
You're checking a 2D array. You'd need to use [i][0] and [j][0]
You can try only splicing valuesDATA
Try
for (var i = 0; i < valuesDATA.length; i++) {
for (var j = 0; j < valuesCheckSeeding.length; j++) {
if (valuesDATA[i][0] == valuesCheckSeeding[j][0]) {
valuesDATA.splice(i, 1);
i--; //account for the splice
break; //go to next i iteration of loop
}
}
}
Logger.log(valuesDATA);
Alternatively, try
valuesCheckSeeding = valuesCheckSeeding.map(function(e){return e[0];}); //flatten this array
var filteredArr = valuesDATA.filter(function(e){
return !(this.indexOf(e[0])+1);
},valuesCheckSeeding);
Logger.log(filteredArr);

How to programmatically create 3D array that increments to a defined number, resets to zero, and increments again?

Starting with this initial 2D array:
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
I need to create this 3D array programmatically:
var fullArray = [
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]],
[[6,7],[3,4],[1,2],[5,6],[2,3],[6,7]],
[[0,1],[4,5],[2,3],[6,7],[3,4],[0,1]],
[[1,2],[5,6],[3,4],[0,1],[4,5],[1,2]],
[[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]],
[[3,4],[0,1],[5,6],[2,3],[6,7],[3,4]],
[[4,5],[1,2],[6,7],[3,4],[0,1],[4,5]],
[[5,6],[2,3],[0,1],[4,5],[1,2],[5,6]]
];
See the pattern?
On each pair, the [0] position should increment to 6 (from any starting number <= 6) and then reset to 0 and then continue incrementing. Similarly, the [1] position should increment to 7 (from any starting number <= 7) and then reset to 1 and then continue incrementing.
In this example, there are 10 2D arrays contained in the fullArray. However, I need this number to be a variable. Something like this:
var numberOf2DArraysInFullArray = 12;
Furthermore, the initial array should be flexible so that initialArray values can be rearranged like this (but with the same iteration follow-through rules stated above):
var initialArray = [[6,7],[2,3],[5,6],[4,5],[1,2],[6,7]];
Any thoughts on how to programmatically create this structure?
Stumped on how to gracefully pull this off.
Feedback greatly appreciated!
Here's a solution, I've separated the methods, and I made it so if instead of pairs it's an N size array and you want the [2] to increase up to 8 and reset to 2, if that's not needed you can simplify the of the loop for(var j = 0; j < innerArray.length; j++)
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var create3DArray = function(array, size){
var newArray = [initialArray];
for(var i = 0; i < size; i++)
{
newArray.push(getNextArrayRow(newArray[i]));
}
return newArray;
}
var getNextArrayRow = function(array){
var nextRow = [];
for(var i = 0; i < array.length; i++)
{
var innerArray = array[i];
var nextElement = [];
for(var j = 0; j < innerArray.length; j++)
{
var value = (innerArray[j] + 1) % (7 + j);
value = value === 0 ? j : value;
nextElement.push(value);
}
nextRow.push(nextElement);
}
return nextRow;
}
console.log(create3DArray(initialArray,3));
Note, the results from running the snippet are a bit difficult to read...
var initialArray = [[2,3],[6,7],[4,5],[1,2],[5,6],[2,3]];
var numOfArrays = 10;
// get a range array [0, 1, 2, ...]
var range = [];
for (var i = 0; i < numOfArrays; i++) {
range.push(i);
}
var result = range.reduce(function(prev, index) {
if (index == 0) {
return prev;
}
prev.push(transformArray(prev[index - 1]));
return prev;
}, [initialArray])
console.log(result);
function transformArray(arr) {
return arr.map(transformSubArray)
}
function transformSubArray(arr) {
return arr.map(function(val) {
return val == 7 ? 0 : val + 1;
})
}
Here's a pretty simple functional-ish implementation

How to generate an array with repeated string javascript

How to generate an array with function like this?
var name = ["monkey","monkey"..."horse","horse",..."dog","dog",..."cat","cat"...]​
In my real case, I may have to repeat each name 100 times..
Assuming that you already have that words in a array try this code:
var words = ["monkey", "hourse", "dog", "cat"];
var repeatWords = [];
for(var i = 0; i < words.length; i++)
{
for(var j = 0; j < 100; j++)
{
repeatWords.push(words[i]);
}
}
You can try this, specifying the words to be used, and the times to create the array you need.
var neededWords = ["Cat", "Hourse", "Dog"];
var finalArray = [];
var times = 10;
for (var i = 0; i < neededWords.length; i++) {
for (var n = 0; n < times; n++) {
finalArray.push(neededWords[i]);
}
}
console.log(finalArray);
Hope that helps!
If I understood correctly you need a function that takes as an argument a collection of items and returns a collection of those items repeated. From your problem statement, I assumed that the repetition has to be adjusted by you per collection item - correct me if I am wrong.
The function I wrote does just that; it takes an object literal {name1:frequency1,name2:frequency2..} which then iterates over the keys and pushes each one as many times as indicated by the associated frequency in the frequencyMap object.
function getRepeatedNames( frequencyMap ) {
var namesCollection = [];
Object.keys(frequencyMap).forEach(function(name,i,names){
var freq = frequencyMap[name];
freq = (isFinite(freq)) ? Math.abs(Math.floor(freq)) : 1;
for (var nameCounter=0; nameCounter<freq; nameCounter++) {
namesCollection.push(name);
}
});
return namesCollection;
}
Non-numeric values in the frequency map are ignored and replaced with 1.
Usage example: If we want to create an array with 5 cats and 3 dogs we need to invoke
getRepeatedNames({cat: 2, dog: 3}); // ["cat","cat","dog","dog","dog"]

Javascript arrays storing values

There might be a very simple solution my problem but just not being able to find one so please help me to get to my solution in the simplest way...
The issue here is that I have data being displayed in a tabular form. Each row has 5 columns and in one of the columns it shows multiple values and so that's why I need to refer to a value by something like this row[1]['value1'], row[1]['value2'] & then row[2]['value1'], row[2]['value2'].
I declare the array
var parray = [[],[]];
I want to store the values in a loop something like this
for(counter = 0; counter < 10; counter ++){
parray[counter]['id'] += 1;
parray[counter]['isavailable'] += 0;
}
Later I want to loop through this and get the results:
for (var idx = 0; idx < parray.length; idx++) {
var pt = {};
pt.id = parray[schctr][idx].id;
pt.isavailable = parray[schctr][idx].isavailable;
}
Obviously iit's not working because Counter is a numeric key and 'id' is a string key ..my question how do I achieve this ??
Thanks for all the answers in advance.
JS has no concept of "associative arrays". You have arrays and objects (map). Arrays are objects though, and you can put keys, but it's not advisable.
You can start off with a blank array
var parray = [];
And "push" objects into it
for(counter = 0; counter < 10; counter++){
parray.push({
id : 1,
isAvailable : 0
});
}
Then you can read from them
for (var idx = 0; idx < parray.length; idx++) {
// Store the current item in a variable
var pt = parray[idx];
console.log(pt);
// read just the id
console.log(parray[idx].id);
}
Like I did here
What you want inside your array is just a plain object:
// just a regular array
var parray = [];
for(var counter = 0; counter < 10; counter++){
// create an object to store the values
var obj = {};
obj.id = counter;
obj.isavailable = 0;
// add the object to the array
parray.push(obj);
}
later:
for (var idx = 0; idx < parray.length; idx++) {
var pt = parray[idx];
// do something with pt
}

Categories

Resources