Summarize the text and stick all the letters together - javascript

I have a text and want to summarize it , i want change this array :
Array 1
[
'CALX', '11.10', '21',
'01', '08', 'EGLD',
'USDT', 'LDFDFC', 'ZONE',
'238.5', '233', 'LEVERAGE',
'3', 'X', 'TARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'H',
'GD', 'S', 'AFCA'
]
to this :
Array 2
[
'CALX', '11.10', '21',
'01', '08', 'EGLDUSDTLDFDFCZONE',
'238.5', '233', 'LEVERAGE',
'3', 'XTARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'HGDSAFCA',
]
as you can see , I want all the letters to stick together until they reach a number,and each number should be in an element of the array
This is the code that can be used to convert text to an Array1
const input = 'CALX, [11.10.21 01:08] $EGLD/USDT #Ldfdfc zone : 238.5 - 233 "LEVERAGE" : 3x TARGET1 : 243.9 TARGET 2 : 248 TARGET 3 : 254 TARGET 4 : 260 h.gd.s afca. `~!##$%^&*()_-+=-/?><'
const text = text.toUpperCase().match(/[a-z]+|\d+(?:\.\d+)?/gi);
so how can i change the Array1 to Array2?
sorry for my English and thank you for your help.

Based on the initial string, to get the desired array as output you don't have to convert it to an array to process it again.
You can use a pattern similar like the one that you tried with an alternation | but instead of matching [a-z]+ you can capture 1 or more non digits using (\D+) in a group.
Then in the callback of replace, you can remove the unwanted characters if there is a match for the group 1. The unwanted characters are [\W_]+ or one more non word chars including the underscore.
If there is no group, you can return the match (the digits) between delimiters, where you can split on the delimiters afterwards to create the final array.
const input = 'CALX, [11.10.21 01:08] $EGLD/USDT #Ldfdfc zone : 238.5 - 233 "LEVERAGE" : 3x TARGET1 : 243.9 TARGET 2 : 248 TARGET 3 : 254 TARGET 4 : 260 h.gd.s afca. `~!##$%^&*()_-+=-/?><'
text = input
.toUpperCase()
.replace(/\d+(?:\.\d+)?|(\D+)/g,
(m, g1) => g1 ? g1.replace(/[\W_]+/g, '') : `#${m}#`
);
console.log(text.split(/#+/));

One of the solution could look like this:
let arr = [
'CALX', '11.10', '21',
'01', '08', 'EGLD',
'USDT', 'LDFDFC', 'ZONE',
'238.5', '233', 'LEVERAGE',
'3', 'X', 'TARGET',
'1', '243.9', 'TARGET',
'2', '248', 'TARGET',
'3', '254', 'TARGET',
'4', '260', 'H',
'GD', 'S', 'AFCA'
]
function handleArray(a) {
let result = [];
let stringItem = '';
a.forEach((el) => {
// If number then check if we have previous string and push
// it to the result.
// Also push number as next element
if (/\d/.test(el)) {
if (stringItem) {
result.push(stringItem);
// Clear string variable
stringItem = '';
}
result.push(el)
} else {
// Concat ongoing string, don't push to result
stringItem += el;
}
})
return result;
}
console.log(handleArray(arr))

Related

inverting object boolean property with ! vs =false , Is there any difference?

I am trying to make tic tac toe game in vanilla javascript. If I use ! to flip the value of object boolean property , it is changed to what it is defined in global memory object (as soon as it is out of its execution context), however If I flip by using = equal sign, it stays same. aren't they both doing same thing(flipping value)?? Any explanation would be appreciated.
Here's my code.
// we need an object for storing the state of our game.
const game = {
xTurn: true,
xState: [],
oState: [],
winningStates: [
// Rows
['0', '1', '2'],
['3', '4', '5'],
['6', '7', '8'],
// Columns
['0', '3', '6'],
['1', '4', '7'],
['2', '5', '8'],
// Diagonal
['0', '4', '8'],
['2', '4', '6']
]
}
document.addEventListener('click',e=>{
const target = e.target;
console.log('initializing code')
const isCell = target.classList.contains('grid-cell')
const isDisabled = target.classList.contains('disabled');
if(isCell && !isDisabled){
const cellValue = target.dataset.value;
if(game.xTurn){
game.xState.push(cellValue)
}else{
game.oState.push(cellValue)
}
target.classList.add('disabled')
target.classList.add(game.xTurn ? 'x' : 'o')
// if(game.xTurn){
// target.classList.add('x')
// }else{
// target.classList.add('o')
// }
console.log(game.xTurn)
game.xTurn = !game.xTurn;
// game.xTurn = false;
console.log(game.xTurn)
}
})

Why is my program only detecting integer tokens in NodeJS?

I decided to try and make a language tokenizer (don't even know if that's a real word) and made around 4 tokens that successfully tokenized a full program with line breaks and multiple spaces etc, but I just started from scratch and am running into a problem; I have two tokens currently, int and variableSet. The program being read has the content of 1 sv 1 2 as just a test, and the tokenizer returns an array of int, int, int, int with sv having a value of 1.
const code = `1 sv 1 2`
var validTokens = require("./tokens"); // just an object with the structure tokenName: RegExp object
function reverseTokenSearch(regex){
for (const [index, [key, value]] of Object.entries(Object.entries(validTokens))) {
if (value === regex){
return key;
}
}
return false;
}
function throughTokens (code,lastidx=0) {
for (const tokentype in validTokens){ // loop through all of the valid tokens
validTokens[tokentype].lastIndex = lastidx;
const searchresult = validTokens[tokentype]
const tokenresult = searchresult.exec(code.toString());
if (tokenresult) {
return [searchresult, tokenresult[0], tokenresult.index, lastidx+tokenresult[0].length+1, tokenresult.groups]
}
}
}
function resetIndexes (){
for (const tt in validTokens){
validTokens[tt].lastidx = 0;
}
}
resetIndexes();
var lst = 0
var tokens = []
var res = 1;
console.log("\ntokenizer; original input:\n"+code+"\n");
while (lst !== undefined && lst !== null){
if (lst > code.length){
console.error("Fatal error: tokenizer over-reached program length.")
process.exit(1)
}
const res = throughTokens(code,lst);
if(res){
console.log(res,lst)
const current = []
current[0] = reverseTokenSearch(res[0])
current[1] = res[1]
const currentidx = 2
for (const x in res[4]) {
current[currentidx] = x;
}
tokens.push(current)
lst = res[3]
} else {
lst = null
}
}
console.log(tokens)
// What outputs:
/*
tokenizer; original input:
1 sv 1 2
[ /\d+/g { lastidx: 0 }, '1', 0, 2, undefined ] 0
[ /\d+/g { lastidx: 0 }, '1', 5, 4, undefined ] 2
[ /\d+/g { lastidx: 0 }, '1', 5, 6, undefined ] 4
[ /\d+/g { lastidx: 0 }, '2', 7, 8, undefined ] 6
[ [ 'int', '1' ], [ 'int', '1' ], [ 'int', '1' ], [ 'int', '2' ] ]
*/
I think it's because of the order of the array but I have no idea where to start fixing it and would greatly appreciate a push in the right direction.
(edit): I tried removing the "g" flag on the RegExp object and all it did was broke the program into an infinite loop.
The problem is that you are silently assuming that every match found by the regex will start at lastidx which is not always the case. If you log tokenresult and lastidx before returning from throughTokens, you will see:
0
[ '1', index: 0, input: '1 sv 1 2', groups: undefined ]
2
[ '1', index: 5, input: '1 sv 1 2', groups: undefined ]
4
[ '1', index: 5, input: '1 sv 1 2', groups: undefined ]
6
[ '2', index: 7, input: '1 sv 1 2', groups: undefined ]
In the second iteration, the match is at index 5, but you assume it to be at index 2, which it is not (whereby you also incorrectly increment lastidx to 4). You also at the end of throughTokens assume that every match is followed by a space, which is also incorrect for the last token.
Simplest way to fix this code is to replace
//if (tokenresult) { // replace in throughTokens with below
if (tokenresult && tokenresult.index === lastidx) {
to be sure that you're matching at the right place and then in the main loop
//while (lst !== undefined && lst !== null){ // replace with below
while (lst !== undefined && lst !== null && lst < code.length){
to handle the end of the input correctly.
With these changes, the printouts that we added earlier will be
0
[ '1', index: 0, input: '1 sv 1 2', groups: undefined ]
2
[ 'sv', index: 2, input: '1 sv 1 2', groups: undefined ]
5
[ '1', index: 5, input: '1 sv 1 2', groups: undefined ]
7
[ '2', index: 7, input: '1 sv 1 2', groups: undefined ]
which is correct and the output would be
[
[ 'int', '1' ],
[ 'variableSet', 'sv' ],
[ 'int', '1' ],
[ 'int', '2' ]
]
Recommendations
There are a lot of other logical and programmatical problems with this code which I will not go into but my advice is to go through every piece of the code and understand what it does and whether it could be done in a simpler way.
On a general level instead of returning an array with data [d1, d2, d3, ...] return an object with named properties { result: d1, index: d2, ... }. Then it is much easier for someone else to understand your code. Also go through naming of methods.
As far as this approach is concerned, if you know that there will be a space after each token, then extract only the current token and send to throughToken. Then you can make that function both more efficient and robust against errors.

Best way to access key, value pair inside of an array of objects? in javascript

I'll try my best to explaing as throughly as possible but first I'll just paste what I have so far:
var test = 'select imei, phone_number from userinfo';
const result = await pgClient.query(test);
const resultString = result.rows;
var a = [];
for(let i = 0; i < resultString.length; i +=1){
let obj = resultString[i];
//let data = [obj];
// res = data.reduce((acc, curr) => {
// acc[curr.imei] = curr.phone_number;
// return acc;
// }, {} );
a.push(obj)
}
console.log(a)
so basically after querying that select statment, I get an obj like this {imei, number} and then push that to an array so it more looks like this
var jsObjects = [
{imei: '11', number: '+11'},
{imei: '12', number: '+12'},
{imei: '13', number: '+13'},
{imei: '14', number: '+14'}
];
But if you uncomment the code above and replace a.push(obj) with a.push(res) it can also look like this
[
{ '11': '+11' },
{ '12': '+12'},
]
So the MAIN reason for all of this is becasue im trying to create a function so that
if (a.imei('11')) {
return a.phonenumber('+11')
}
Return the phone number associated with the given imei number.
And the actual question is which format is best to access key, value pair? and how would i access the actual value based on the key? Sorry for being all over, I really dont know how else to explain and ask this. Thank you
I think I understand that you'd like a fast lookup of a number value given an "imei" value. The loop as written in the OP doesn't do anything to the result string except move the same values into a new array called a, so either with a or resultString, do this...
const jsObjects = [
{imei: '11', number: '+11'},
{imei: '12', number: '+12'},
{imei: '13', number: '+13'},
{imei: '14', number: '+14'}
];
const imeiIndex = jsObjects.reduce((acc, obj) => {
acc[obj.imei] = obj.number;
return acc;
}, {});
console.log(imeiIndex)
With that, given an "imei" value later, the associated number can be looked up fast with...
let someImeiValue = '14';
let quicklyLookedupNumber = imeiIndex[someImeiValue]; // <- this will be '+14'
Also, note...
It's often a good idea to keep the whole object being indexed in the way just described, like this:
const jsObjects = [
{imei: '11', number: '+11', someOtherProp: 1 },
{imei: '12', number: '+12', someOtherProp: 2 },
{imei: '13', number: '+13', someOtherProp: 3 },
{imei: '14', number: '+14', someOtherProp: 4 }
];
const imeiIndex = jsObjects.reduce((acc, obj) => {
acc[obj.imei] = obj; // <-- NEW: store the whole object in the index
return acc;
}, {});
// now indexed data contains as much info as the original array
console.log(imeiIndex);
let key = '12';
console.log(`the object at key ${key} is ${JSON.stringify(imeiIndex[key])}`);

Javascript array filter function removes key values

I have an array of Javascript objects indexed by key values listed below, each key representing a Javascript object (this is just a console.log() of the key values in the array):
[ '532',
'789',
'1232',
'2346',
'3404',
'4991',
'5323',
'5378',
'8923',
'9876',
'23434',
'23549',
'24454',
'34234',
'45667',
'48983',
'67834',
'72342',
'82434',
'89829',
'98732',
'123404',
'143454',
'234345',
'345294',
'532234',
'532342',
'532345',
'532349',
'989898' ]
When I console.log() out this Javascript array it is "filled-in" with "NULL" values. For example the first key is 532, so when printing this array out first there are 531 "NULL" values printed and the then Javascript object with key 532 and so on for each key.
So my solution is to remove the null values by running this function below on the array:
teamData = teamData.filter(function (el) {
return el != null && el != "";
});
My Issue:. Once I run that filter function the array key values are reset to:
[ '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'10',
'11',
'12',
'13',
'14',
'15',
'16',
'17',
'18',
'19',
'20',
'21',
'22',
'23',
'24',
'25',
'26',
'27',
'28',
'29' ]
Question: Is there a way to filter out the null values between the array keys while still keeping the key values in the first array? Is there another way to structure this data so there won't be null values?
Problem is that you're trying to use an array index position as key. This won't work because arrays always have consecutive indexes starting from 0. So if you gonna have an element at index 532 then there necessarily will be 532 elements before it (0 to 531). If you remove those elements with filter the indexes will shift to the correct position, in your case from 0 o 29. In Javascript there is a native object for your use case, it is called Map, here you can read everything about it.

how to turn an array of bytes into a string in javascript [duplicate]

This question already has answers here:
Converting byte array to string in javascript
(16 answers)
Closed 8 years ago.
I am getting a response from a SOAP server and it is an array of bytes, fixed size.
For instance, I get { rsp: { errorNumber: '1', errorMessage: { item: [Object] } } }
[ '73',
'110',
'118',
'97',
'108',
'105',
'100',
'32',
'112',
'97',
'115',
'115',
'119',
'111',
'114',
'100',
'0']
How do I turn that array to a string it javascript?
Each "byte" in your array is actually the ASCII code for a character. String.fromCharCode will convert each code into a character.
It actually supports an infinite number of parameters, so you can just do:
String.fromCharCode.apply(String, arr);
When ran on your array you get: "Invalid password".
As #Ted Hopp points out, the 0 at the end is going to add a null character to the string. To remove it, just do: .replace(/\0/g,'').
String.fromCharCode.apply(String, arr).replace(/\0/g,'');
Here's one more alternative using map:
var str = arr.map(String.fromCharCode).join("");
Here is what you want, the String.fromCharCode function:
var foo = [
'73',
'110',
'118',
'97',
'108',
'105',
'100',
'32',
'112',
'97',
'115',
'115',
'119',
'111',
'114',
'100',
'0'];
var str = '';
for (var i=0; i<foo.length; ++i) {
str+= String.fromCharCode(foo[i]);
}
console.log(str);
Or better :
var str = String.fromCharCode.apply(null, foo);

Categories