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('.');
});
Related
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);
I have some tasks to handle in my daily jobs, so I need to do it in a automatic way. My task is:
there will be some messages sent to my IM, and I need to append the first, second & third number to each links with a "|".
if there only 2 numbers in the number line, a 0 is needed in the first place.
For example, in the cleanResult example, I need it to be done like:
finalResult = ["https://www.example.com/firstlink|500",
"https://www.example.com/firstlink|150",
"https://www.example.com/firstlink|30",
"https://www.exmaple.com/secondlink|600",
"https://www.exmaple.com/secondlink|150",
"https://www.exmaple.com/secondlink|30",
"https://www.example.com/thirdlink|500",
"https://www.example.com/thirdlink|150",
"https://www.example.com/thirdlink|30",
"https://www.example.com/forthlink|600",
"https://www.example.com/forthlink|100",
"https://www.example.com/forthlink|20",
"https://www.example.com/fithlink|0",
"https://www.example.com/fithlink|200",
"https://www.example.com/fithlink|50"
]
Here's the codes I had done so far:
const urlRegex = /(https?\:\/\/)?([^\.\s]+)?[^\.\s]+\.[^\s]+/gi;
const digitRegex = /^(?=.*\d)[\d ]+$/;
cleanResult = ["https://www.example.com/firstlink",
"https://www.exmaple.com/secondlink",
"https://www.example.com/thirdlink",
"500 150 30",
"https://www.example.com/forthlink",
"600 100 20",
"https://www.example.com/fithlink",
"200 50"
]
cleanResult.forEach((item, index) => {
if (item.match(digitRegex)) {
//codes I don't know how to do...
}
})
Are elements in cleanResult always either a URL or a number? In that case, you could just check the first character of the string to see if it's a number (basically a non-url). If it's not a URL, then we know it's numbers, and we can do something with the URL, which should the the previous element:
// If it's a URL, we will store it here for future use
let currentURL = ''
cleanResult.forEach((item, index) => {
// Get the first character of this string
const first = item[0]
if (!Number.isInteger(first)) {
// This is NOT a number, so must be a URL,
// let's store it in our variable to use in the next loop
currentURL = item
} else {
// This IS a number, which means we need to do a few things:
// 1. Split into separate numbers
// 2. Create a new URL pattern from each number
// 3. Push to finalResult
// 1. Split by tab delimiter (?)
// splits by tab, and returns an array
const numbers = item.split('\t')
// 2. Create a new URL pattern from each number
numbers.forEach((n) {
// This should now give you the URL + | + the number:
// ex: https://example.com/firstlink|500
const newURL = currentURL + '|' + n
// 3. push to the finalResult array
finalResult.push(newURL)
})
}
})
I haven't tested it, but this is the process that I generally use: break it into smaller tasks and take it one step at a time. I also didn't use regex, just to make it easier. We're assuming that you will receive either a URL or a list of numbers separated by a tab. This means you can afford to keep it a bit simple.
I'm sure there are way more efficient ways to do it and in a lot fewer lines, but if you're just learning JS or programming, there is nothing wrong with being extra verbose so that you can understand early concepts.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
There is a list of product data. Each product item has a string-type name-property.
How could a viable transformation look like that does convert a product-name into a valid HTML id-attribute value?.
Viable means that a transformation is build in a way that there should be almost no chance for generating identical id's from two different but similar constructed product names.
The naming of common products looks like this ...
"2-inch leg extension"
"2' x 8' Overhead Garage Storage Rack"
"4 Drawer Base Cabinet 16-1/2"W x 35"H x 22-1/2"D"
"24" Long Tool Bar w/ Hooks Accessory"
Transformed validly the above list might look like that ...
"z2-inchlegextension"
"z2x8OverheadGarageStorageRack"
"z4DrawerBaseCabinet16-12Wx35Hx22-12D"
"z24LongToolBarwHooksAccessory"
One could consider providing a prefix (e.g. "z") to the to be generated id in oder to make it a valid HTML id-attribute.
I'm not familiar with replacement techniques that assure results which will be repeatable consistent.
How could a possible transformation approach look like?
You can try this-
const data = [
"2-inch leg extension",
"2' x 8' Overhead Garage Storage Rack",
"4 Drawer Base Cabinet 16-1/2\"W x 35\"H x 22-1/2\"D",
"24\" Long Tool Bar w/ Hooks Accessory"
];
const res = data.map(str => str.replace(/[^a-z\d\-_]/ig, ''));
console.log(res);
If you need any prefix with the ID then add it like-
const prefix = 'Z';
const res = data.map(str => prefix + str.replace(/[^a-z\d\-_]/ig, ''));
The simplest answer that fulfills your requirement:
string.replace(/[^A-Za-z]/g, "");
If there are no letter characters this will result in an empty string. But since IDs need to start with letters anyway, you need special handling for cases where your product names have no letters in them
The following approach creates configurable identifiers.
It also preserves as much information of a given product name as possible in order to prevent the accidental creation of identifier duplicates.
It does so by translating the string patterns of technical measures, units and terms as much as it could be anticipated from the examples provided by the OP.
const productNameList = [
"2-inch leg extension",
"2' x 8' Overhead Garage Storage Rack",
'4 Drawer Base Cabinet 16-1/2"W x 35"H x 22-1/2"D',
'24" Long Tool Bar w/ Hooks Accessory'
];
function createIdentifier(str) {
const config = this;
const prefix = config.prefix || '_';
const separator = config.separator || '';
const id = [prefix, str
// replace foot symbol that follows immediately after a digit
.replace((/([\d])'/g), `$1${ separator }Ft`)
// replace inch symbol (double quote character)
.replace((/"/g), `${ separator }In${ separator }`)
// replace times character enclosed by word boundaries
.replace((/\bx\b/g), 'Times')
// replace digit connector, a minus symbol enclosed by digits
.replace((/([\d])-([\d])/g), `$1${ separator }And${ separator }$2`)
// replace division symbol that is enclosed by digits
.replace((/([\d])\/([\d])/g), `$1${ separator }By${ separator }$2`)
// uppercase any character that follows a word boundary
.replace((/\b([\w])/g), ([$1]) => $1.toUpperCase())
// replace/delete all non word characters.
.replace((/[\W]+/g), separator)
].join('');
return ((separator && id.toLowerCase()) || id);
}
console.log(
productNameList,
' => HTML id attribute => ',
productNameList.map(createIdentifier, { prefix: 'pid_' })
);
console.log(
productNameList,
' => HTML id attribute (long) => ',
productNameList.map(createIdentifier, { prefix: 'pid_', separator: '-' })
);
console.log(
productNameList,
' => valid JS variable name => ',
productNameList.map(createIdentifier)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
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);
});
How would I convert something like 1200000 to £1.2m but also convert 2675000 to £2.675m
i can get the second one to work but the first one comes out as £12m rather than £1.2m
I have the number in a variable so.
salePrice.toString().replace(/0+$/g, '').replace(/\B(?=(\d{3})+(?!\d))/g, '.')}m
how would i change the second replace to work as I guess it is that one that is causing the issue.
as long as this passes
1200000
1220000
1222000
1222200
1222220
1222222
1020000
1022200
so on and so forth all of them need to be able to pass.
You have Number.prototype.toFixed() option available.
const data = [
2675000,
1200000,
1220000,
1222000,
1222200,
1222220,
1222222,
1020000,
1022200
];
const formatted = data.map(x=> (x/1000000).toFixed(3).replace(/0+$/g, '')); // ["2.675", "1.2", "1.22", "1.222", "1.222", "1.222", "1.222", "1.02", "1.022"]
I haven't included the part with the currency, because you had that figured out already. Shilly's answer is really beautiful. I'm simply proposing another solution, which is a bit shorter.
You divide them by the precision you need. I would advice to keep numbers as numbers as long as possible, since strings used as numbers follow text rules instead of math rules, so you'd have to parse them back to numbers to do anything meaningful apart from formatting the output.
const data = [
2675000,
1200000,
1220000,
1222000,
1222200,
1222220,
1222222,
1020000,
1022200
];
const format_currency = ( prefix, value, precision, suffix ) => `${ prefix }${ value / precision }${ suffix }`;
const million = {
symbol: 'm',
value: 1000000
};
const pounds = '£';
const results = data.map( entry => format_currency( pounds, entry, million.value, million.symbol ));
console.log( results );