How to order by string by Month name using javascript? - javascript

I have a string "APRIL,AUGUST,JULY,JUNE,MAY". I want to order it by month name.
The required output is APRIL,MAY,JUNE,JULY,AUGUST.

You can keep order list of all months and do the sorting based on that:
const order = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "AUGUST", "SEPTEMBER", "OCTOBER", "NOVEMBER", "DECEMBER"];
const sort = (data) =>
data
.split(',')
.sort((a, b) => order.indexOf(a) - order.indexOf(b))
.join()
const data1 = 'APRIL,AUGUST,JULY,JUNE,MAY'
console.log(sort(data1))
const data2 = 'APRIL,AUGUST,JULY,JUNE,MAY,APRIL'
console.log(sort(data2))

The easiest solution is probably:
const s = "APRIL,AUGUST,JULY,JUNE,MAY";
const months = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "OCTOBER", "SEPTEMBER", "NOVEMBER", "DECEMBER"]
let resultArray = [];
months.forEach(month => {
if (s.includes(month)) {
resultArray.push(month);
}
})
console.log(resultArray.join(','));

Use Array#filter() on preordered array and check if each name exists in the string
const s = "APRIL,AUGUST,JULY,JUNE,MAY";
const months = ["JANUARY", "FEBRUARY", "MARCH", "APRIL", "MAY", "JUNE", "JULY", "OCTOBER", "SEPTEMBER", "NOVEMBER", "DECEMBER"]
const res = months.filter(m => s.includes(m)).join()
console.log(res)

The other solutions might be inefficient because they rely on the String.includes or Array.indexOf prototypes, which cost alone O(n) (where n is the length of the input string).
I propose an alternative solution that uses a dictionary, which supports indexing in amortized O(1) time.
The overall time complexity is O(m logm), where m is the number of months in the input string.
You can index month names in monthNamesObj in amortized O(1) time.
const input = "APRIL,AUGUST,JULY,JUNE,MAY";
// inputMonthNames = ['APRIL', 'AUGUST', 'JULY', 'JUNE', 'MAY']
const inputMonthNames = input.split(',');
// dictionary that maps month names to the correspective order index
const monthNamesObj = {
'JANUARY': 0,
'FEBRUARY': 1,
'MARCH': 2,
'APRIL': 3,
'MAY': 4,
'JUNE': 5,
'JULY': 6,
'AUGUST': 7,
'SEPTEMBER': 8,
'OCTOBER': 9,
'NOVEMBER': 10,
'DECEMBER': 11,
};
// sort the input month names according to their numeric order
const orderedMonths = inputMonthNames.sort((a, b) => monthNamesObj[a] - monthNamesObj[b]);
// APRIL,MAY,JUNE,JULY,AUGUST
console.log(orderedMonths.join(','));

Related

slice strings of an array in javascript

i am getting below array.
Array [
"מאי 2017",
"יוני 2017",
"ינואר 2018",
"פברואר 2018",
"מרץ 2018",
"מאי 2018",
"יוני 2018",
"נובמבר 2019",
"אוגוסט 2020",
"נובמבר 2020",
"דצמבר 2020",
"ינואר 2021",
]
and i have an english month array.
const englishMonthArray = [
"",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
]
how can i match only months of above array with English months?Thanks
Create a dictionary object that maps the Hebrew month (key) to the English equivalent (value).
map over the array. split the string on the space, get the English month from the dictionary, and then return a new string.
const arr=["מאי 2017","יוני 2017","ינואר 2018","פברואר 2018","מרץ 2018","מאי 2018","יוני 2018","נובמבר 2019","אוגוסט 2020","נובמבר 2020","דצמבר 2020","ינואר 2021"];
const dict = {
ינואר: 'January',
פברואר: 'February',
מרץ: 'March',
אַפּרִיל: 'April',
מאי: 'May',
יוני: 'June',
יולי: 'July',
אוגוסט: 'August',
יולי: 'September',
יולי: 'October',
נובמבר: 'November',
דצמבר: 'December'
};
const out = arr.map(el => {
// This was interesting. For an English string
// this would be destructured like [year, month].
// I'm assuming that because there's Hebrew in the string
// JS/the browser reads it differently (right to left).
const [ month, year ] = el.split(' ');
const enMonth = dict[month];
return `${year} ${enMonth}`;
});
console.log(out);
Additional documentation
Template/string literals
Destructuring assignment

Cannot read property 'sky' of undefined

I want to display an Icon and use parameteres that API gives me back. Whenever I try to do it, I get undefined. Tryed to do this like this :
import React from 'react';
import './WeatherBox.css'
import { Icons } from '../../icons';
const dateBuilder = (d) => {
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
let day = days[d.getDay()];
let date = d.getDate();
let month = months[d.getMonth()];
let year = d.getFullYear();
return `${day} ${date} ${month} ${year}`
}
const WeatherBox = ({result}) => {
return (
<div className="locationDate">
<span>{result.location}</span>
<span>{dateBuilder(new Date())}</span>
<span>{result.temp}°C</span>
{/* <span>{Icons.Clouds}</span> */}
<span>{result ? Icons.result.sky : null}</span>
</div>
)
}
export default WeatherBox;
result.sky is variable that API gives me back, something like "Clouds" "Sunny" etc. that's how my icons are named and i want to display them when API is loaded. Condition I used doesn't work, and It wants to display before API is even returned.
The answer is I tried to refer to Icons wrong. Instead of using Icons.result.sky, i had to do It like Icons[result.sky].

vue.js referencing constants in data?

Just wondering, I have the following setup:
new Vue({
el: '#app',
const: {
monthNames : ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
},
data: {
year : (new Date()).getFullYear(),
month : (new Date()).getMonth(),
monthName : this.monthNames[(new Date()).getMonth()],
day : (new Date()).getDate(),
},
...
)}
As you can see, I'm trying to pass in (new Date()).getMonth() into the monthNames array from const - but console is returning the Uncaught TypeError: Cannot read property '4' of undefined.
So my question is simply: how do I reference monthNames from within data?
N.B. I'm using the most recent js dev build.
You could declare it outside the Vue instance or perhaps in another module and import it before using like import { monthNames } from './constants', and then use it whenever you want.
If you want to keep it inside that particular Vue instance then i think it would be better to put it inside the computed structure for caching.
Example:
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
new Vue({
el: '#app',
data: {
year : (new Date()).getFullYear(),
month : (new Date()).getMonth(),
monthName : monthNames[(new Date()).getMonth()],
day : (new Date()).getDate(),
},
...
)
A question that matches yours: https://stackoverflow.com/a/46883212/7395911
A discussion about a constant structure within Vue: https://github.com/vuejs/vue/issues/6004
I'm a newbie to Vue but you can attach it to the Vue simply by calling:
Vue.prototype.$monthNames
And then calling it within data using monthNames
From what I can find you can also use mixins (seems a bit dangerous, affects all components) or simply just declaring a constant before loading the Vue instance.

moment.js year/number format with arabic locale

I am formatting dates using moment.js with arabic locale (ar_SA) set.
moment.locale('ar_SA');
moment([2016,05,01]).format('MMM YYYY');
//output مايو ٢٠١٦
I would like to format only the month part using the locale, but the year in english, example: "مايو 2016" (the same as when formatting using the angular filter: | date:'MMM yyyy')
Is there a way to configure moment.js to do this automatically? (instead of splitting the month and year formatting and simply concatenating 2016 to .format('MMM'))
moment.updateLocale('en', {
months : [
"January", "February", "March", "April", "May", "June", "July",
"August", "September", "October", "November", "December"
]
});
Source: https://momentjs.com/docs/#/customization/month-names/
I never did find a solution to this. I opted for a split/manual approach instead:
currentDate.format('MMM') + ' ' + currentDate.clone().locale('en').format('YYYY');

CultureInfo in JavaScript

In c# I use the below method in order to get the CultureInfo.
System.Globalization.CultureInfo.CurrentCulture.Name // output :en-US
Can any one tell me how can I get the CultureInfo in JavaScript?
Very easy way is to render it into the view, like this:
<script>
var cultureInfo = '#System.Globalization.CultureInfo.CurrentCulture.Name';
</script>
This is razor syntax, if you use classic asp.net, then use:
<script>
var cultureInfo = '<%= System.Globalization.CultureInfo.CurrentCulture.Name %>';
</script>
This is a very old post an is definately in need of an update. All major browsers now support the navigator property. Simply use
var lang = navigator.language
It depends on your goal. If you want the entire website to be treated as the same culture as your server, you can use System.Globalization.CultureInfo.CurrentCulture.Name only and remove the if-then shorthand within the first code snippet. This is not advisable if you have a global website.
Include the following in the bottom of your page:
<input id="currentCulture" type="hidden" value="<%=((Request.UserLanguages != null && Request.UserLanguages.Length > 0) ? new System.Globalization.CultureInfo(Request.UserLanguages.First(), true).Name : System.Globalization.CultureInfo.CurrentCulture.Name) %>" />
Now you can retrieve the culture info specific to the user, within your javascript, using:
$("#currentCulture").val(); //Jquery
document.getElementById("currentCulture").value; //Pure javascript
Within your code behind, any datetime parsing you require, pass in the culture info provider to the parse and tryparse and Convert.ToDateTime functions by using the below:
CultureInfo info = ((Request.UserLanguages != null && Request.UserLanguages.Length > 0) ? new CultureInfo(Request.UserLanguages.First(), true) : System.Globalization.CultureInfo.CurrentCulture);
Note: if you use Jquery UI and have cultures not included by default (such as en-CA or en-GB), you will have to add them. You can retrieve the code here:
https://code.google.com/p/dobo/source/browse/trunk/dobo/Kooboo.CMS/Kooboo.CMS.Web/Scripts/jquery-ui-i18n/?r=7
You can then include it dynamically by following the below example:
$.datepicker.regional['en-CA'] = { "Name": "en-CA", "closeText": "Close", "prevText": "Prev", "nextText": "Next", "currentText": "Today", "monthNames": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December", ""], "monthNamesShort": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", ""], "dayNames": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], "dayNamesShort": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], "dayNamesMin": ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"], "dateFormat": "dd/mm/yy", "firstDay": 0, "isRTL": false };
$(".datepick").datepicker($.datepicker.setDefaults($.datepicker.regional[$("#currentCulture").val()]));

Categories