Is there a one-liner to convert '1234567' into ['1234', '567', '', '']? - javascript

I need to convert a string into an array with 4 elements, each element has maximum of 4 characters.
"1234567812345678" -> ["1234", "5678", "1234", "5678"]
"12345678123" -> ["1234", "5678", "123", ""]
"" -> ["", "", "", ""]
The reason I want it to be a one-liner is that I need to put it into vue template string so it needs to be an expression other than a series of statements.
I don't want to create a dedicated function to just convert a single parameter to another form.
I managed to split the string into an array but I don't know how to fill in empty slots with '', here's a simplified snippet:
const creditcard = '12345678123';
// need a one liner
const groups = creditcard.split(/(?<=^(?:.{4})+)/);
console.log(groups);

You could pad the string to minimum 16 characters with spaces, then trim the results
const creditcard = '12345678123';
// need a one liner
const groups = creditcard.padEnd(16, ' ').split(/(?<=^(?:.{4})+)/).map(v => v.trim());
console.log(groups);

Another option is to allocate an array with four elements and populate it with splices from your input:
const input = '111122223333444';
const output = Array(4).fill().map((_, i) => input.split('').splice(i*4, 4).join(''));
console.log(output);
// ["1111", "2222", "3333", "444"]

Use slice you can achieve your goal
Here is the code:
function splitToArray(n) {
const ret = [];
for(let i = 0; i < 16; i += 4) {
ret.push(n.slice(i, i + 4))
}
return ret;
}
console.log(splitToArray(''));
console.log(splitToArray('1234567812345678'));
console.log(splitToArray('12345678123'));

Related

Javascript Check Array with Object Keys using includes() but do not check the whole word

I have the following code. A body object and a sensitive word array.
If the body key contains any word from sensitive words, it should returns true.
const body = {
name: "",
email: "",
otpp: ""
}
const sensitiveWords = ["password", "pin", "otp"]
const isSensitive = sensitiveWords.some(el => Object.keys(body).map(name => name.toLowerCase()).includes(el)) || false
console.log(isSensitive);
// returns: false
// expected result: true
But as you can see, the word otp is in the sensitive words, but its not matching otpp. I guess its because its looking for full string match.
I need the above function to return true since the key contains otp in otpp.
Thank you.
You're looking for
const containsSensitive = sensitiveWords.some(el =>
Object.keys(body).some(name =>
// ^^^^
name.toLowerCase().includes(el)
// ^^^^^^^^ string search
)
)
I provide an solution using double some() to do it
const body = {
name: "",
email: "",
otpp: ""
}
let sensitiveWords = ["password", "pin", "otp"]
const isSensitive = (body,words) => Object.keys(body).map(n => n.toLowerCase()).some(d1 => words.some(d2 => d1.includes(d2)))
console.log(isSensitive(body,sensitiveWords)) // true
sensitiveWords = ["password", "pin", "otps"]
console.log(isSensitive(body,sensitiveWords)) // false
You can try using regex with case insensitive flag (i). This could be more performant than using two nested loops.
const body = {
name: '',
email: '',
password: ''
}
const sensitiveWords = ['password', 'pin', 'otp']
const sensitiveWordsRegex = new RegExp(sensitiveWords.join('|'), 'i')
const keys = Object.keys(body)
const hasSensitiveWord = keys.some(key => sensitiveWordsRegex.test(key))
console.log(hasSensitiveWord)
The answer of Bergi is the best one.
I just want to share what I worked on, I realized I made it so complicated.
Btw to explain why your code did not work is because:
You were searching the array for a word (the body object keys array Object.keys(body)) -- this will not work because you are basically comparing strings and not searching it for a substring
What you need to do is search the string for a substring
You'll have to iterate through the body keys and search each for a substring --> string.includes('string)
JsFiddle link
/*
** The answer of Bergi is the best one but just want to share what I worked on
** (https://stackoverflow.com/a/74150607/8414995)
** if you want it the hard way
*/
// Check if strings from an array matches a key (substring or whole word) of an object
const body = {
name: '', email: '', otpp: '',
}
// list of words to be searched in the body keys
const sensitiveWords = ['password', 'pin', 'otp']
// list down the keys first maybe to make the code clearer?
const bodyKeys = Object.keys(body)
// search through each word from sensitiveWords
const hasData = sensitiveWords.some(el => {
// iterate through each word from bodyKeys and check if the sensitive word matches a substring of the body key. Filter only the true values
const result = bodyKeys.map(bEl => {
// return true if it matches anything
if (bEl.includes(el)) {
return true
}
}).filter(el => el == true)
// the result will be in array form so let's just check if the length > 0
return !!result.length
})
console.log(hasData)
// Check if strings from an array matches a key (substring or whole word) of an object
I would try to json stringify the whole body and split to words and search on that

Split an array of strings with each string containing more than one space

I have an array of strings like this. Both left and right portions in the string are separated with spaces (More than 1 space for each).
const arr = [
'A1789 Other tuberculosis of nervous system',
'A179 Tuberculosis of nervous system, unspecified',
'A1801 Tuberculosis of spine'
];
I need to turn this into an array of objects like this, with the first portion as the key and the second portion as the value of the key.
const arrOfObj = [
{ A1789: 'Other tuberculosis of nervous system' },
{ A179: 'Tuberculosis of nervous system, unspecified' },
{ A1801: 'Tuberculosis of spine' }
];
I would split by space, assuming your key cannot contain space. So we'll have first item your key and the "rest" your value, which we can trim
arr.map(s => {
const [key, ...value] = s.split(" ");
return { [key]: value.join(" ").trim() }
})
I'd think something like this would work:
const arrOfObj = {};
arr.forEach(item => {
const match = str.match(/^([A-Za-z0-9]+)\s+(.+)/);
arrOfObj[match[1]] = match[2];
});

How to get particular part of string from an array of strings using javascript?

Hi below is array of strings
const arr = [
"list/1/item/1/",
"some-domain/2/item/2/",
"item/3/",
"some-domain/4/item/5/subitem/1/",
]
i have to filter those strings that start with string "item/3/" or ends with string "item/3/"
so from above array expected filtered array is like below,
const filtered_arr = [
"list/1/item/1/",
"some-domain/2/item/2/",
"item/3/",
]
from the filtered array i want to get the number after "/item/". so from above filtered array the expected output is
const arr_ids = ["1", "2", "3"]
what i have tried,
i have used below to match those strings that start or end with /item/3/
const filtered_arr = arr.map(str) => {
return str.match(/item\/[0-9](\/)?$/g);
}
this gives the filtered_arr
const filtered_arr = [
"list/1/item/1/",
"some-domain/2/item/2/",
"item/3/",
]
but how do i map through each array item and get the number after string "/item/".
could someone help me with this. thanks.
Use filter to filter paths either starting or ending in item/\d+/. Then use map to extract the item number from each matching path.
const arr = [
"list/1/item/1/",
"some-domain/2/item/2/",
"item/3/",
"some-domain/4/item/5/subitem/1",
];
var output = arr.filter(x => x.match(/^item\/\d+|\bitem\/\d+\/$/))
.map(x => x.match(/(?<=^item\/)\d+|(?<=\bitem\/)\d+(?=\/$)/)[0]);
console.log(output);
This may help:
const filtered_arr = arr.map(str) => {
const match = str.match(/\/item\/(\d)/);
return(match[1]);
}

join array elements with specified element to be placed at the end

I have an array
input = ["Hi","Bye","Hello","Jose","Juan",null,"How","","Disco"]
I want to always place the word "Bye" to the end of the joined string
I have tried with
input.filter(Boolean).join("#"))
expected output
"Hi#Hello#Jose#Juan#How#Disco#Bye"
I am looking for the best efficient way, or if there is a way to add a filter function along with Boolean filter
Use a filter function that compares with Bye after performing the boolean test.
Then append #Bye to the end of the result.
input = ["Hi", "Bye", "Hello", "Jose", "Juan", null, "How", "", "Disco"];
console.log(input.filter(s => s && s != 'Bye').join("#") + '#Bye');
1) Filter input array that are not empty, null and along with filter you can count of Bye(There can be multiple Bye)
2) Create a new array that only contains Bye using Array.from and append it after the filtered array.
3) Then, at last, you can join array.
const input = ["Hi", "Bye", "Hello", "Jose", "Juan", null, "How", "", "Disco"];
let length = 0;
const result = input
.filter((s) => {
if (s === "Bye") ++length;
return s && s !== "Bye";
})
.concat(Array.from({ length }, () => "Bye"))
.join("#");
console.log(result);
Sort the Byes to the end?
const input = ['Hi', 'Bye', 'Hello', 'Jose', 'Juan', null, 'How', '', 'Disco'];
const output = input
.filter(Boolean)
.sort((a, b) => (a === 'Bye') - (b === 'Bye'))
.join('#');
console.log(output);
If it is a string then one way to get the result is to
const outputString=input.filter(Boolean).join("#"))+"#bye"

Split one array in two arrays with react native

I would like to split an array into two arrays (one for letters and the other for frequencies).
var list = [ "ES 324798", "LE 237076", "EN 231193" ]
This is the array that I want to split.
I would like to get an array with all letters like this :
var letters = [ "ES", "LE", "EN" ]
And an other with numbers :
var numbers = [ "324798", "237076", "231193" ]
I searched for "how to split one array in two arrays with React native" but I don't find what I want. I tried with split and splice functions but it didn't help me (or I just don't know how to use them properly).
Can you give me some tips ?
One possible solution could be using .reduce() and .split().
Try the following:
const list = [ "ES 324798", "LE 237076", "EN 231193" ];
const result = list.reduce((a, c) => {
const split = c.split(' ');
a.letters.push(split[0]);
a.numbers.push(split[1]);
return a;
}, { letters: [], numbers: [] });
const { letters, numbers } = result;
console.log('letters', letters);
console.log('numbers', numbers);
I hope this helps!
This is not about React Native.
I would do:
const letters = []
const numbers = []
list.forEach((item) => {
const [ letter, number ] = item.split(' ')
letters.push(letter)
numbers.push(number)
})

Categories

Resources