find string in field of object - Javascript - javascript

I have string:
city = 'Hải Phòng'
and an array that I get from an API which looks like this:
data = [{},{},{},{ MaTinhThanh: 'xx', TenTinhThanh: 'Hải Phòng' },{},{}]
I want to find an object in my data:
mycity = data.find( c=>c.TenTinhThanh.includes(city))
the above gives undefined, but I expect
{ MaTinhThanh: 'xx', TenTinhThanh: 'Hải Phòng' }
My API endpoint is:
https://donhang.vnpost.vn/api/api/TinhThanh/GetAll
I am using visual code, Axios, nodejs
I also tried the getting the length of both strings:
data[3].TenTinhThanh.length` ====>11
city.length` ====>9
What is the problem?

Your two strings don't contain the same characters, even though the appear to be visually the same:
const city = "Hải Phòng";
const objV = "Hải Phòng";
console.log(city === objV); // false
This is because you're using the precomposed forms of:
ả (latin small letter a with hook above)
ò (latin small letter o with grave)
in your search string city. These precomposed characters are legacy unicode characters, instead, you should be using the decomposed forms, which are the characters being used in your object value:
ả (latin small letter a a, followed by combining hook above ̉)
ò (latin small letter o o, followed by combining grave accent ̀)
(yes, these are different to the ones listed previously). You can do this by updating your city to hold "Hải Phòng" (which uses the decomposed characters for ả and ò). If you can't decompose your string for whatever reason, you can use String.prototype.normalize() on your input string or your object string, eg:
const city = 'Hải Phòng'.normalize("NFD"); // or just use `const city = "Hải Phòng";`
const data = [{},{},{},{ MaTinhThanh: 'xx', TenTinhThanh: 'Hải Phòng' },{},{}];
const mycity = data.find( c=>c.TenTinhThanh?.includes(city));
console.log(mycity);

Check that the property exists in the first place, then match against that city value. It looks like there may have been something wrong with the encoding of the strings, because I received an error before I copied the city var value to the object.
Edit: It looks like another user laid out this issue in detail.
let city = 'Hải Phòng';
const data = [{},{},{},{ MaTinhThanh: 'xx', TenTinhThanh: 'Hải Phòng' },{},{}];
let mycity = data.find(c => c.TenTinhThanh && c.TenTinhThanh === city);
console.log(mycity);

Related

Translate Special Characters with npm latinize is not working dynamically

I am using latinize to translate german language's special characters to English, they module work only when I pass string within single or double quotes, but not when I pass by storing them inside a variable.
import latinize from 'latinize';
ANd inside render, I console this and it works fine,
console.log('render', latinize('VfL Osnabrück'))
also when i pass my
let tag_name = 'VfL Osnabrück';
console.log('render', latinize('VfL Osnabrück'))
it will again works fine, but did not work fine when I get tag_name from my api. And complete code is below
let tag_parsing = sub_category_id.split('%20');
let tag_string = '';
for (let i = 0; i < tag_parsing.length; i++) {
tag_parsing[i];
// tag_parsing[0] == Vlf
// tag_parsing[1] == Osnabrück
console.log('latinized text', tag_parsing[i]);
tag_string += ' ' + tag_parsing[i]
}
OUTPUT
output of latinized text ==> Osnabr%C3%BCck
output of latinized text inside quotes ==> Osnabruck
I also try with .toString() but did not work
I think there may be something off with how you are attempting to process the query string from the URL.
Here's a snippet of the logic I used to process your query string in a forked codesandbox. I used a functional component for ease, but the same logic can be used in a class-based component.
// get the search string
const { search } = useLocation();
const [latinizedValue, setLatinizedValue] = React.useState("");
React.useEffect(() => {
console.log({ search });
// create search params object
const newParams = new URLSearchParams(search);
const key = newParams.get("key");
const value = newParams.get("value")?.trim();
console.log("Param", key, `"${value}"`);
console.log("latinize param:", `"${latinize(value)}"`);
setLatinizedValue(latinize(value));
}, [search]);
Demo
The font-family that i was using was not contains special german characters, and finally I changed the font-family that supports german special characters, and everything goes smooth and latinize also works fine.

Facing issue in restricting the amount of splits

I have used the below code to split my string.
splitter.map((item1) => {
let splitter1 = item1.split("=")[0].trimLeft();
let splitter2 = item1.split("=")[1].trimRight();
});
where item1 contains string as
Labor_Agreement=0349BP
Default_Hours=5/8
Probation_Period=>=12 Months
The issue I am facing is to restrict the amount of splits. Because the above code will fail in case of third string , i.e. Probation_Period=>=12 Months
I tried giving parameter to restrict the amount of split in split method above, but that is giving syntax error.
An easy to understand solution would consist of first finding the first = character, and slicing you array twice to get the right portion :
const strings = [
'Labor_Agreement=0349BP',
'Default_Hours=5/8',
'Probation_Period=>=12 Months',
];
strings.map(item => {
const chSplit = item.indexOf('=');
const splitter1 = item.slice(0, chSplit).trim();
const splitter2 = item.slice(chSplit + 1).trim();
console.log(splitter1, splitter2);
});

VueJS: Computed Calculation Assistance

I need to be able to convert a string (IP address) such as this 10.120.0.1 to a string (ISIS Network ID) such as this 49.0001.0101.2000.0001.00. The middle section 010 1.20 00.0 001 corresponds to the first string (I've spaced them out to show the IP address is inside it). You can see that there are 4 digits in each ISIS Network ID hextet that need to correspond to 3 digits in the IP Address octet. A number of 53 for example would have a leading 0 to make 3 digits.
All the IP addresses start with 10.120. so I just need to inject the last 2 octets from the IP Address into the ISIS Network ID.
I need this to be dynamic so when someone types in another ip address into a loopbackIP input, it automatically updates the isisNetworkID field.
I have this:
49.0001.0101.{{ isisNetworkID }}.00
This needs to take the value from an input v-model="loopbackIP" that I have and translate the remaining values to sit in the middle of that isisNetworkID following this format - xxxx.xxxx.
I've got this computed calculation but I'm not sure how to make 4 digits equal 3...
const loopbackIP = '10.120.0.1';
const isisNetworkID = computed(() => {
let idaho = '10.120.';
if (loopbackIP.indexOf(idaho)) {
return loopbackIP.slice(7);
} else {
console.log('Nothing is happening');
}
});
I hope this makes sense...
I think I understand what you're trying to achieve. Let's break it down into digestible parts. You have an IP address of:
10.120.0.1
And you want to transform it such that each part is padded to 3 digits:
['010', '120', '000', '001']
This can be done by splitting the string by the . character, and the using String.prototype.padStart(). We then join the array back into a string:
'010120000001'
||||
^^^^ -> to be deleted
We know that the first 4 digits is not needed, since it's already part of your template, so we can remove them using String.prototype.substring(4). That leaves us with:
'20000001'
Now it is just the matter of splitting it into 4 characters per item:
['2000', '0001']
...and rejoining it with . character:
'2000.0001'
...and interpolating it back into the string. I have a proof-of-concept example below, which should output the desired string:
const loopbackIP = '10.120.0.1';
const parts = loopbackIP.split('.').map(x => x.padStart(3, '0'));
// Remove the first 4 characters
let isisNetworkId = parts.join('');
isisNetworkId = isisNetworkId.substring(4);
const output = `49.0001.0101.${isisNetworkId.match(/.{4}/g).join('.')}.00`;
console.log(output);
So if you want to translate it to your VueJS code, it should look no different that this:
const loopbackIP = '10.120.0.1';
const isisNetworkID = computed(() => {
const loopbackIP = '10.120.0.1';
const parts = loopbackIP.split('.').map(x => x.padStart(3, '0'));
let isisNetworkId = parts.join('');
isisNetworkId = isisNetworkId.substring(4);
// Rejoin, split into items of 4-character long, rejoin by period
return isisNetworkId.match(/.{4}/g).join('.');
});

Why will indexOf() not return the location of an email address in the array?

I have an array of email addresses that I obtained using .getViewers() from my sheet. This gives me the array of
[xxxxxjrhigh#xxxxxxx.org, /hd/domain/xxxxxxx.org, testemail3#googlemail.com, testemail2#gmail.com, testemail1#gmail.com]
Note: xxxxxxx replacing sensitive information
I am trying to remove the following from that array and then send an email to the remaining email addresses.
xxxxxjrhigh#xxxxxxx.org -and- /hd/domain/xxxxxxx.org
The index results always come back as -1 (no match found).
I'm new to coding so I'm sure it is an easy fix that I am just not aware of. I have tried putting my search term in 'single' quotes, in "double" quotes, and in no quotes at all. I tried assigning it to a variable and then using the variable in the indexOf(variable). I've watch 3 different tutorials on using indexOf() that do not indicate that I should have any trouble.
var viewers = SpreadsheetApp.getActiveSpreadsheet().getViewers();
Logger.log(viewers);
var index = viewers.indexOf('/hd/domain/xxxxxxx.org');
Logger.log(index);
viewers.splice( index, 1);
Logger.log(viewers);
var index = viewers.indexOf('xxxxxjrhigh#xxxxxxx.org');
Logger.log(index);
viewers.splice( index, 1);
Logger.log(viewers);
var string = ""+viewers;
Logger.log(string);
GmailApp.sendEmail(string, 'Test Treacker', 'This is the outcome from the test tracker');
Results I have been getting from the log:
index = -1.0
index = -1.0
string = xxxxxjrhigh#xxxxxxx.org,/hd/domain/xxxxxxx.org,testemail3#googlemail.com,testemail2#gmail.com
What I expect to get:
index = 0
index = 1
string = testemail3#googlemail.com,testemail2#gmail.com
You can take a look at what getViewers() call returns here: https://developers.google.com/apps-script/reference/spreadsheet/spreadsheet.html#getviewers. It is not an array of strings, but rather an array of User objects, each of which has a getEmail() method. The reason why your indexOf() returns a -1 for every email is that you are not working with an array of simple strings here!
To remove two users from the array based on their email you could do something like this:
const viewers = SpreadsheetApp.getActiveSpreadsheet().getViewers();
const filteredViewers = viewers.filter(viewer =>
viewer.getEmail() !== 'email1' && viewer.getEmail() !== 'email2');
Where email1 and email2 are emails of users you don't want to have in your resulting array.
Thank you #ajobi for pointing me in the right direction. While your code didn't help me because of the odd syntax error, your revelation that the items in my viewers array where accounts instead of actual email addresses got me thinking and doing a little more research. I stumbled on an answer that works for me.
I mapped the array of accounts to change it to an array of actual email addresses. This is what I came up with.
function correctEmails() {
var viewers = SpreadsheetApp.getActiveSpreadsheet().getViewers();
Logger.log(viewers);
var viewers1 = viewers.map(getEmails);
Logger.log(viewers1);
var index = viewers1.indexOf('/hd/domain/xxxxxxx.org');
Logger.log(index);
viewers1.splice( index, 1);
Logger.log(viewers1);
var index = viewers1.indexOf('xxxxxjrhigh#xxxxxxx.org');
Logger.log(index);
viewers1.splice( index, 1);
Logger.log(viewers1);
var string = ""+viewers1;
Logger.log(string+" - string");
// GmailApp.sendEmail(string, 'Test Treacker', 'This is the outcome from the test tracker');
//
}
function getEmails(item) {
return item.getEmail();
}
This results in the string I was looking for of testemail3#googlemail.com,testemail2#gmail.com and it will work no matter what order the email accounts are in.
Thanks!

Regex split string and check if string is of type

Aanval op Vlemis (499|453) C44
This is what the string looks like. Though it's actually like this: "Aanval op variable (variable) variable
What I want to do is 1: get the coordinates (I already have this), 2 get Vlemis (first variable), get C44 (third variable) and check to see if the string is of this type.
My code:
$("#commands_table tr.nowrap").each(function(){
var text = $(this).find("input[id*='editInput']").val();
var attackername= text.match(/(?=op)[\s|\w]*(?=\()/);
var coordinates = text.match(/\(\d{1,3}\|\d{1,3}\)/);
});
Coordinates works, attackername however doesn't.
Html:
<span id="labelText[6]">Aanval op Vlemis (499|453) C44</span>
You should use one regex to take everything :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/).slice(1);
This builds
["Vlemis", "499", "453", "C44"]
If you're not sure the string is valid, test like this :
var parts = text.match(/(\w+)\s*\((\d+)\|(\d+)\)\s*(\w+)/);
if (parts) {
parts = parts.slice(1);
// do things with parts
} else {
// no match, yell at the user
}

Categories