Add string content to array of dates using map - javascript

How can I add strings that are separated using colon present in two input fields with the format hh:mm:ss to a range of dates selected that is stored something like this, ["11.10.2022 23:43:24","28.10.2022 23:43:24"] . I am using dayjs for date related actions. Help will be appreciated
Code that I tried
const from = "12:49:55";
const to = "10:45:55";
const range = ["11.10.2022 23:43:24","28.10.2022 23:43:24"];
const timeAdded = range?.map(
(value: Dayjs, index: number) => {
if (index === 0) {
return dayjs(from, "hour").add(from, "minute").add(from, "second");
}
if (index === 1) {
return dayjs(to, "hour").add(to, "minute").add(to, "second");
}
}
);
How can I add both the values in one go. Output should look like
["11.10.2022 12:49:55","28.10.2022 10:45:55"]

You can do it without days.js:
const from="12:49:55", to="10:45:55";
const times=[from,to];
const range = ["11.10.2022 23:43:24","28.10.2022 23:43:24"];
const timeAdded = range.map((r,i)=>r.replace(/ .*/," "+times[i]));
console.log(timeAdded);

Related

Convert Comma-separated Values Into Tags React Native with TypeScript

I want to convert comma-separated values into tags. In fact I already have a good part done, but I have a problem. the tags come "added" with the previous ones. If I type in the input "ex1,ex2", the tags "ex1" and "ex1,ex2" will be created, but the tags that should be created are "ex1" and "ex2". look: .
this is my input:
<Input
onChangeText={(text: string) => handleTagChange(text)}
onKeyPress={handleTagKey}
value={inputTag}
/>
and here is the functions:
const handleTagChange = (text: string) => {setInputTag(text);}
const handleTagKey = (event: NativeSyntheticEvent<TextInputKeyPressEventData>) =>
{
const { key } = event.nativeEvent;
const trimmedInput = inputTag.trim();
if(key === ',' && trimmedInput.length && !tags.includes(trimmedInput)) {
event.preventDefault();
setTags((prev) => [...prev, trimmedInput]);
}
}
I thought it would be enough to set an empty string in the input value after setTags (setInputTag("")), but apparently it's not that simple.
would this work for you?
setTags(trimmedInput.split(","));
you must first remove the last comma

How to find similarities between a text string and an array?

I have a string array, which I want to compare with a text string, if it finds similarities I want to be able to mark in black the similarity found within the string
example:
context.body: 'G-22-6-04136 - PatientName1'
newBody: ['G-22-6-04136 - PatientName1' , 'G-22-6-04137 - PatientName2']
When finding the similarity between the two the result would be something like this
newBody: [**'G-22-6-04136 - PatientName1'** , 'G-22-6-04137 - PatientName2']
How could I do it? Is this possible to do? In advance thank you very much for the help
const totalSize: number = this.getSizeFromAttachments(attachments);
const chunkSplit = Math.floor(isNaN(totalSize) ? 1 : totalSize / this.LIMIT_ATTACHMENTS) + 1;
const attachmentsChunk: any[][] = _.chunk(attachments, chunkSplit);
if ((totalSize > this.LIMIT_ATTACHMENTS) && attachmentsChunk?.length >= 1) {
const result = attachment.map(element => this.getCantidad.find(y => element.content === y.content))
const aux = this.namePatient
const ans = []
result.forEach(ele => {
const expected_key = ele["correlative_soli"];
if (aux[expected_key]) {
const newItem = { ...ele };
newItem["name_Patient"] = aux[expected_key]
newItem["fileName"] = `${expected_key}${aux[expected_key] ? ' - ' + aux[expected_key] : null}\n`.replace(/\n/g, '<br />')
ans.push(newItem)
}
});
let newBody: any;
const resultFilter = attachment.map(element => element.content);
const newArr = [];
ans.filter(element => {
if (resultFilter.includes(element.content)) {
newArr.push({
fileNameC: element.fileName
})
}
})
newBody = `• ${newArr.map(element => element.fileNameC)}`;
const date = this.cleanDateSolic;
const amoung= attachmentsChunk?.length;
const getCurrent = `(${index}/${attachmentsChunk?.length})`
const header = `${this.cleanDateSolic} pront ${attachmentsChunk?.length} mail. This is the (${index}/${attachmentsChunk?.length})`;
console.log('body', context.body);
// context.body is the body I receive of frontend like a string
const newContext = {
newDate: date,
amoung: amoung,
getCurrent: getCurrent,
newBody: newBody,
...context
}
return this.prepareEmail({
to: to,
subject: ` ${subject} (Correo ${index}/${attachmentsChunk?.length})`,
template: template,
context: newContext,
}, attachment);
}
I have a string array, which I want to compare with a text string, if it finds similarities I want to be able to mark in black the similarity found within the string
First of all the text will be in black by default, I think you are talking about to make that bold if matched. But again it depends - If you want to render that in HTML then instead of ** you can use <strong>.
Live Demo :
const textString = 'G-22-6-04136 - PatientName1';
let arr = ['G-22-6-04136 - PatientName1', 'G-22-6-04137 - PatientName2'];
const res = arr.map(str => str === textString ? `<strong>${str}<strong>` : str);
document.getElementById('result').innerHTML = res[0];
<div id="result">
</div>
Based on your example, it looks like the string needs to be an exact match, is that correct?
Also, "mark it in bold" is going to depend on what you're using to render this, but if you just want to wrap the string in ** or <b> or whatever, you could do something like this:
newBody.map(str => str === context.body ? `**${str}**` : str);
You can just see if string exists in the array by doing
if arr.includes(desiredStr) //make text bold

How to filter values of an array inside an array?

I will describe the situation for more clarity. I have an array
like this
animalsArray = {
animalID : number,
animalName: string,
animalDescription: string,
animalChild: animalsArray[]
}
Now I have to filter these animals using animalName from user input by textfield. Some animals can have n number of animalChild or non at all or animalChild can have another animalChild inside it.
I already have a code like this
public animalsArray:animalsArray[]
this.filteredanimalsArray.next(
this.animalsArray.filter(item => (item.animalName.toLowerCase().indexOf(search) > -1))
);
To filter the main animalsArray and it works fine but the user input doesn't go through the child arrays.
How can I solve this problem? Thanks in advance
Maybe you could use recursivity like this :
function filterAnimals(animals, name) {
return animals.filter(animal => {
const matching = animal.animalName.toLowerCase() === name.toLowerCase();
const hasChildMatch = Array.isArray(animal.animalChild) && filterAnimals(animal.animalChild, name).length > 0;
return matching || hasChildMatch;
});
}
const search = 'leon';
const filterdAnimals = filterAnimals(animalsArray, search);

How to filter last day in an array?

I have an array of objects like this:
[
{
created: "2019-08-14T13:24:36Z",
email: "test1#gmail.com"
},
{
created: "2019-08-15T13:24:36Z",
email: "test2#gmail.com"
},
{
created: "2019-08-16T13:24:36Z",
email: "test1#gmail.com"
},
{
created: "2019-08-22T13:24:36Z",
email: "test4#gmail.com"
},
{
created: "2019-08-22T15:29:66Z",
email: "test1#gmail.com"
}
]
The array is sorted by created. I want to filter those records which are on the last day, irrespective of the time on that day. I added the timestamp using moment.js. Something on these lines:
router.get('/GetLastDayRecords', (req, res) => {
res.json(allRecords.filter(record => record.created.max()));
});
Split the task: first get the maximum date which you'll find at the end of the sorted array (just getting the "YYYY-MM-DD" part of it is enough) and then launch the filter:
let max = allRecords.length ? allRecords[allRecords.length-1].created.slice(0,10) : "";
res.json(allRecords.filter(({created}) => created >= max));
First you need to figure out which day is the last day. If you can assume the records are already sorted, then this is pretty simple:
// Assuming your records are stored in the variable "records"
var lastDay = records[records.length - 1].created;
Now here's where your specific answer may differ based on how you want to handle time zones. Suppose one event happened at 11 PM EST (3 AM GMT) and another event happened at 1 AM EST (5 AM GMT). Are these the same day? In Europe they are, but in America they aren't!
What you need to do is create some cipher from the date+time listed to a "day". This way you can compare two "days" to see if they're the same:
lastDay = new Date(lastDay);
// Setting hours, minutes, and seconds to 0 will give you just the "day" without the time, but by default will use the system timezone
lastDay.setHours(0);
lastDay.setMinutes(0);
lastDay.setSeconds(0);
Once you know which day was the last, it's a simple filter:
// Using a for loop
var results = []
for (var i = 0; i < records.length; i++)
{
if (records[i].created > lastDay) {
results.push(records[i]);
}
}
// Using .filter
var results = records.filter(x => x.created > lastDay);
Alternatively, since we know it's already sorted, we can do it a bit more efficiently by binary searching for the first record on the last day, then grabbing all records after that:
var test = records.length / 2;
var step = records.length / 4;
var found = false;
while (!found) {
if (records[test].created < lastDay) {
test += step;
step /= 2;
}
else if (records[test].created > lastDay) {
if (step == 1) {
// We found the exact cut-off
found = true;
}
else {
test -= step;
step /= 2;
}
}
}
var results = records.slice(test);
Because you're only interested in the "last" day, the logic is a bit simpler. If you wanted the "third" day, you would need to check if created was after the start of the third day and before the end of the third day. We can just check if it's after the start of the last day.
I would create a function to turn your created properties into data be easily compared.
I would also avoid trying to do the entire filter operation in one or two lines as it will difficult to read by other developers.
const dateToInt = date => parseInt( date.split('T').shift().replace(/-/g, '') );
The above will:
Split your created property into an array of date and time.
Select the first element, which happens to be the date.
Remove the dashes in the date.
Coerce the value into a number.
With this you can find the maximum value and filter based on that value.
const nums = foo.map( ({ created }) => dateToInt(created) )
First get a list of numbers from the dataset.
const max = Math.max( ...nums )
Get the biggest number in the list.
const lastDays = foo.filter( ({ created }) => dateToInt(created) === max )
With all that setup, getting the max date is very easy and readable.
Of course, since the list is already sorted. You could have just done this as well.
const last = foo[foo.length -1].created;
const lastDays = foo.filter( ({ created }) => created === last )
I wrote a solution using reduce and filter:
const lastDay = arr.reduce((acc, el) => {
const date = el.created.substr(0,10);
const oldDate = new Date(acc);
const nextDate = new Date(date);
if(oldDate.getTime() > nextDate.getTime()) {
return oldDate;
} else {
return nextDate;
}
}, '1900-01-01');
const lastDayArr = arr.filter(el => {
const date = el.created.substr(0,10);
const oldDate = new Date(lastDay);
const nextDate = new Date(date);
return (oldDate.getTime() === nextDate.getTime());
});
First, you find the most recent date, reducing the original array by comparing which date is the most recent, for this you drop the part of the created string that specifies the hours/minutes/seconds.
You can use a very distant in time date as initial value, or you can set it to null and add another validation in your callback function.
As a second step, you use filter, using the same technique of dropping the hours/minutes/seconds of the created string.
The end result is an array of the elements with the most recent date in your original array.
If you can assume the array is sorted, you can skip the reduce method and just do:
const lastDay = arr[arr.length - 1].created.substr(0,10);
This should work:
allRecords.filter( record => {
let last_date = allRecords[ allRecords.length - 1].created
return last_date.slice(0, 10) === record.created.slice(0, 10)
})
Basically, you are getting the last element from your array and slicing its created value down to its date. Then you are slicing your current record's created value down to its date and comparing if they are the same.
Assuming that the array is already ASC ordered:
const onLastDay = values.filter( v => {
const last = moment(values[ values.length - 1 ].created)
const differenceInDays = last.diff(moment(v.created), 'days')
return differenceInDays < 1
})
console.log(onLastDay)
NOTE: If you try with the reported array you get an error due the fact that the last date is not valid! There are 66 seconds!

formatting number in input react

I have made an Input component. If it is a number I want to format it correctly, like a currency. I.e. 4000 would be 4,000.
Here is a codesandbox.
I am having issues with displaying and updating this.
<Input initialValue={'400000000'} isNumber={true} />
My Input component looks like this.
type Props = {
initialValue?: string;
isNumber?: boolean;
};
const Input = ({ initialValue = '', isNumber }: Props) => {
const [value, updateValue] = useState(initialValue);
const update = (val: any) => {
if (isNumber) {
const x = Number(val);
updateValue(x.toLocaleString());
} else {
updateValue(val);
}
};
return (
<StyledInput
type="text"
value={value}
onChange={e => update(e.target.value)}
/>
);
};
I am seeing an error NaN in my input component. Anyone have any ideas?
Javascript has a number formatter (part of the Internationalization API).
// Quick Solution With Intl.NumberFormat
const update = (val: any) => {
var formatter = new Intl.NumberFormat("en-US"); // Intl language tag,
updateValue(formatter.format(val.replace(/,/g, ""))); //Remove ',' to format number again
};
Code Snippet:
// Intl.NumberFormat With React State Update
var currentVal = 0;
...
const update = (event: any) => {
/**
https://stackoverflow.com/questions/35535688/stop-cursor-jumping-when-formatting-number-in-react
https://github.com/facebook/react/issues/955
*/
const caret = event.target.selectionStart
const element = event.target
window.requestAnimationFrame(() => {
element.selectionStart = caret
element.selectionEnd = caret
})
// -- Stop cursor jumping when formatting number in React
var val = event.target.value.replace(/(\..*)\./g, '$1') //Replace Multiple Dot(.)
var x = Number(val.replace(/,/g, ""));
if (currentVal != x) {
var formatter = new Intl.NumberFormat("en-US", { minimumFractionDigits:2});
currentVal = formatter.format(x);
updateValue(currentVal);
}else{
updateValue(val);
}
};
return (<input type="text" value={value} onChange={e => update(e)} />);
Note : Code Snippet gives you an idea to format numbers, You need to handle few more use-cases for production.
Also check the react-number-format, Which may suit for your application.
Reference :
Intl.NumberFormat vs Number.prototype.toLocaleString
How can I format numbers as dollars currency string in
JavaScript?
Intl.NumberFormat | MDN
The problem is in
const x = Number(val);
when you evaluate Number("32,423,343"), a string including commas Js will throw an error...
The correct way would be sending the number without commas.. Number("32432343")
To solve it you can add this line to remove the commas, before evaluating to a Number..
val = val.replace(/,/g, '');
https://codesandbox.io/s/r0vm8nxvjo

Categories

Resources