How to convert Alphanumeric Values to value ranges in Typescript? - arrays

myArray = ["AB01","AB02","AB03","AB04","AB11","BC12","BC13", "SB33"];
// expected string "AB01-AB04, AB11, BC12-BC13, SB33"
The letters can be one or two characters. Digits can be two or three characters.
Ex: A001, A002, AB001, AB002, AC01, AC02, B01, B02.
Only these formats are possible.
How to achieve this in a simplified manner?

let myArray = ["AB01","AB05","ABCDEFG01123","ABCDEFG01124","AB02","AB03","AB04","AB11","BC12","BC13", "SB33"];
function getRanges(array, group) {
var ranges = [], rstart, rend;
for (var i = 0; i < array.length; i++) {
rstart = array[i];
rend = rstart;
while (array[i + 1] - array[i] == 1) {
rend = array[i + 1];
i++;
}
ranges.push(rstart == rend ? group+rstart+'' : group+rstart + '-' + group+rend);
}
return ranges;
}
// group first.
let groups = myArray.reduce((groups,item)=>{
let belongsTo = item.match(/[a-zA-Z]/g).join('');
groups[belongsTo] ? groups[belongsTo].push(item) :groups[belongsTo]=[item];
return groups;
},{})
let expectedString = Object.entries(groups).reduce((output,[key,value])=>{
output=`${output}${output.length ? ', ' : ''}${getRanges(value.map(i=>i.match(/[0-9]/g).join('')),key)}`;
return output;
},'');
console.log(expectedString);
// expected string "AB01-AB04, AB11, BC12-BC13, SB33"

Related

loop count number of consecutive cell containing specific word

I'm quite a beginner in JavaScript (well google app script) but now I can manage my work without it. My goal is to send an email to someone when the number of cell containing the word "alert" is equal to 3. I think that the structure of my program might be correct however the syntax may be wrong.
Let me show you what does my program look like for now (I want it to begin on row number 24 and on the 34th column of my sheet):
function onEdit(e) {
let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
//EVENT VARIABLES
let range = e.range;
let row = e.range.getRow();
let col = e.range.getColumn();
let cellValue = sheet.getActiveCell().getValue();
let lastRow = sheet.getLastRow;
let projectName = sheet.getRange(row,1).getValue();
let user = Session.getActiveUser().getEmail();
let cellLocation = sheet.getActiveCell().getA1Notation();
let countAlerte = 0;
let url = "https://docs.google.com/spreadsheets/d/blablabla"
for (i=24;i<=lastRow;i++){
if ((col == 34 && cellValue == "alerte")){
countAlerte = 1;
}
else {
countAlerte = 0;
}
if (countAlerte == 3){
MailApp.sendEmail(
'surname.name#xxx.com',
user + projectName + ' alerte mol 1 ',
url + '&range=' + cellLocation
);
};
}
Is my syntax and variable definition correct?
Is there something wrong with my loop?
You should add 1 instead of assignment:
{
countAlerte = countAlerte + 1; /// or just countAlerte += 1;
}
else {
countAlerte = 0;
}
That is regarding the counting.
Another thing is how do you want to catch onEdit(e). It would be better to get values in the column 34
var valuesInColumn = sheet.getRange(24, 34, lastRow, 1).getValues();
and loop through all values in the valuesInColumn array
for example:
if (col == 34){
var valuesInColumn = sheet.getRange(24, 34, lastRow, 1).getValues();
valuesInColumn.forEach(function(item){
if (item == "alerte"){
countAlerte = countAlerte + 1;
if (countAlerte == 3){
MailApp.sendEmail(
'surname.name#xxx.com',
user + projectName + ' alerte mol 1 ',
url + '&range=' + cellLocation
);
countAlerte = 0;
}
}
else{
countAlerte = 0;
}
});
}

How to get all possibilities for required and optional entries?

The title is not very explicit :')
So there is an example to understand what I want to do :
I have to put a string (as input) which have to look like:
(Hey) (how are you) !
This have to create this string array:
!
Hey !
how are you !
Hey how are you !
Based on the parentheses that have to made all possibilities of string, considering that parenthesis is "optional"
function combs(arr, depth) {
var resp = [], len = arr.length, total = (1 << len);
for (var i = 1; i < total; i++) {
var tmp = [], good = true;
for (var k = 0; k < len; k++) {
if ((i & (1 << k))) {
tmp.push(arr[k]);
}
if (depth && tmp.length > depth) {
good = false;
continue;
}
}
good && resp.push(tmp);
}
return resp;
}
const entries = [{c:"hey",r:false}, {c:" how are you",r:false}, {c:"!",r:true}];
entries.forEach((v,i)=>entries[i].i=i);
const req = entries.filter(v=>v.r);
const opt = entries.filter(v=>!v.r);
const result = [req.map(v=>v.c).join("")];
combs(opt).forEach(v=>{
result.push(req.concat(v).sort((a,b)=>a.i-b.i).map(v=>v.c).join(""))
})
console.log(result)
Firstly, I have to calculate the possibility of having only required elements,
after I calculate all possibility for optional elements only, and I merge each optional possibilities with the only required possibility.
I sort by the index in the origin array.
And I get:
[ '!', 'hey!', ' how are you!', 'hey how are you!' ]
As wanted :)

Problems with includes() function and array comparsion

As a part of whole procedure, I want to compare user's input (as array) with union of two randomly given arrays. I can not use array.sort() and comparison of arrays element by element, because it's enough to have just one different element in input array and after sorting more than just one element will be identified as "wrong one" (example: array "union" after sorting = [11,13,17,18], array "upis" (user's input) after sorting = [7,11,13,18] so if I compare element by element, which I've tried in original code, all first three elements are identified as wrong...)
That's why I've switched to array.includes() and I've spend last 5.5 hours trying to find where am I wrong and just can't find it so I'm going slightly mad... In few hours I'm supposed to be at work but I'm losing my mind because of this...
THE PROBLEM IS WITHIN checkInput() FUNCTION... The code just won't and won't recognize input elements (array "upis") within "union" array... Can't figure out why???
Any help more then appreciated!
<script>
//----------- 1.) Kreiraj dva nasumična niza i uniju -----------
var arrA = []; //od 3 do max 6 članova
var arrB = []; //od 2 do max 5 članova
while (arrA.length < Math.floor(Math.random() * 4) + 3) {
var randomnumber = Math.floor(Math.random() * 20) + 1;
if (arrA.indexOf(randomnumber) > -1) continue;
arrA[arrA.length] = randomnumber;
}
while (arrB.length < Math.floor(Math.random() * 4) + 2) {
var randomnumber = Math.floor(Math.random() * 20) + 1;
if (arrB.indexOf(randomnumber) > -1) continue;
arrB[arrB.length] = randomnumber;
}
var union = [...new Set([...arrA, ...arrB])];
document.write("A = " + arrA + "<br>");
document.write("B = " + arrB + "<br>");
//----------- 2.) Funkcija za dodavanje text box-ova -----------
function addFields() {
// Broj text box-ova koje treba kreirati
var number = union.length;
// <div> u koji će se dinamično dodati text box-ovi
var container = document.getElementById("container");
// Obriši prethodni zapis u <div>
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
// Tekst A U B
//container.appendChild(document.createElement("br"));
container.appendChild(document.createTextNode("A ∪ B = "));
for (i = 0; i < number; i++) {
// Kreiraj <input> element i definiraj stil
var input = document.createElement("input");
input.type = "text";
input.id = "element" + i;
input.style.width = 25;
container.appendChild(input);
// Dodaj zarez poslije svakog input box-a, osim posljednjeg
if (i < number - 1) {
container.appendChild(document.createTextNode(", "));
}
}
// Pokaži gumb Provjeri
document.getElementById("provj").style.visibility = "visible";
}
//----------- 3.) Provjera upisa -----------
function checkInput() {
var upis = [];
var greske = [];
// Pohrani upis u niz
for (i = 0; i < union.length; i++) {
var privr = document.getElementById("element" + i).value;
upis.push(privr);
}
for (i = 0; i < upis.length; i++) {
// ako je neko polje nepopunjeno, obavijesti i prekini petlju
if (upis[i] === "") {
alert("Treba upisati sve članove unije skupova!");
greske = [];
//npr. prva dva upisa kriva, ostala polja nepopunjena - iako ima
//praznih polja, prekida se procedura ali se kod prva dva upisa
//popunio niz greške i onda će ih pokazati
break;
}
// u protivnom
else {
var n = union.includes(upis[i]);
alert(upis[i] + " " + n);
if (n === false) {
greske.push(upis[i]);
} else {
//ništa
}
}
}
if (greske.length > 0) {
alert("Krivo upisani članovi: " + greske);
}
}
</script>
<div id="container">
<button onclick="addFields()">Upiši članove unije</button>
</div>
<button id="provj" style="visibility:hidden" onclick="checkInput()">Provjeri</button>
You are comparing numbers with strings. Just add + to the includes parameter:
var n = union.includes(+upis[i]);
This will force the string to be unboxed as a number and your includes will work as expected.
You other option is to convert those strings to numbers and then no unboxing will be needed.

Multidimensional Arrays and one of the fields

There is a multi-d array and I want to reach specific field in it. I have look around it but I was unable to find proper answer to my question.
My array is like that;
array-md
columns-- 0 | 1 | 2
index 0 - [1][John][Doe]
index 1 - [2][Sue][Allen]
index 2 - [3][Luiz][Guzman]
.
.
.
index n - [n+1][George][Smith]
My question is how can I reach only second column of the array? I tried name = array[loop][1]; but it says "Cannot access a property or method of a null object reference". What is the right way to do that?
Here is main part of the code.
get
var lpx:int;
var lpxi:int;
var arrLen:int = Info.endPageArray.length;
for(lpx = 0; lpx < arrLen; lpx++)
{
for(lpxi = Info.endPageArray[lpx][2]; lpxi < Info.endPageArray[lpx][1]; lpxi++)
{
if(Info._intervalSearch[lpxi] == "completed")
{
successCount++;
Info._unitIntervalSuccess.push([lpx, successCount / (Info._intervalSearch.length / 100)]);
}
}
}
set
for(lpix = 0; lpix < arrayLength; lpix++)
{
if(lpix + 1 <= arrayLength)
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix + 1], Info._UnitsTriggers[lpix]]);
}
else
{
Info.endPageArray.push([lpix, Info._UnitsTriggers[lpix], Info._UnitsTriggers[lpix - 1]]);
}
}
Try this:
var tempArr:Array = [];
function pushItem(itemName:String, itemSurname:String):void
{
var tempIndex:int = tempArr.length;
tempArr[tempIndex] = {};
tempArr[tempIndex][tempIndex + 1] = {};
tempArr[tempIndex][tempIndex + 1][name] = {};
tempArr[tempIndex][tempIndex + 1][name][itemSurname] = {};
}
function getNameObject(index:int):Object
{
var result:Object;
if(index < tempArr.length)
{
result = tempArr[index][index + 1];
}
return result;
}
pushItem("Max", "Payne");
pushItem("Lara", "Croft");
pushItem("Dart", "Vader");
//
trace(getNameObject(0));
trace(getNameObject(1));
trace(getNameObject(2));
Multidimensional array is an array of arrays, which you can create like this :
var persons:Array = [
['John', 'Doe'],
['Sue', 'Allen'],
['Luiz','Guzman']
];
var list:Array = [];
for(var i:int = 0; i < persons.length; i++)
{
list.push([i + 1, persons[i][0], persons[i][1]]);
}
trace(list);
// gives :
//
// 1, John, Doe
// 2, Sue, Allen
// 3, Luiz, Guzman
Then to get some data :
for(var j:int = 0; j < list.length; j++)
{
trace(list[j][1]); // gives for the 2nd line : Sue
}
For more about multidimensional arrays take a look here.
Hope that can help.

Formatting numbers in Angular.js

I have a variable in Angular.js that I should fill like that :
values.push({x: '' + d.x + 'h', y: d.y / 100})
d.x and d.y are numbers that I should display in a ndv3 multiBarChart.But I should format the numbers as if I have 2500, I obtain 2 500.How can I do it ?
I write Angularjs filters Example.jsfiddle
HTML File
<div>
<label >{{"4876931.19" | numberFilter}}</label>
</div>
App Js
angular.module('myApp', ['filters']);
Filter js
angular.module('filters', []).filter('numberFilter', [function () {
return function (number) {
if (!angular.isUndefined(number)) {
var parts = number.split(".");
var str = parts[0].toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1 ");
if(parts[1] !== undefined){
str+="."+parts[1];
}
return str;
}
};
}]);
Updated Code
Here is a small Javascript function which parses the provided number and format it to the desired output:
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
Calling this function with the provided number:
formatNumber(4876931.19) // output will be: 4 876 931.19
function formatNumber(str) {
var parts = (str + "").split("."),
main = parts[0],
len = main.length,
output = "",
i = len - 1;
while(i >= 0) {
output = main.charAt(i) + output;
if ((len - i) % 3 === 0 && i > 0) {
output = " " + output;
}
--i;
}
// put decimal part back
if (parts.length > 1) {
output += "." + parts[1];
}
return output;
}
console.log(formatNumber(4876931.19))

Resources