我需要按月和年对数组进行排序以分别显示在图表上的帮助。
Array1: ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'....];
Desired Output : [....'Apr18','May18','Jun18','Jul18','Jan19','Mar19'];
我还有另一个数组,分别根据上面的数组每个月的值
Array2: ['Mar19_value','Apr18_value','Jun18_value','Jul18_value','May18_value'
,'Jan19_value'....];
Array2: ['55','2','3','0','21','132'....]; //real values
当monthyear
数组排序时,我希望该数组中的数据根据monthyear
的位置移动到新位置。像这样:
Desired Array1: [....'Apr18','May18','Jun18','Jul18','Jan19','Mar19'];
Desired Array2: [....'Apr18_value','May18_value','Jun18_value','Jul18_value','Jan19_value','Mar19_value'];
所以我以后可以这样选择数据:
var label = array[4];
var value = array2[4];
这怎么实现?
答案 0 :(得分:14)
您需要像
一样将字符串更改为new Date(dateString)
format
Array (
[url] => http://adsl.tci.ir/
[content_type] => text/html; charset=UTF-8
[http_code] => 302
[header_size] => 366
[request_size] => 50
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.01543
[namelookup_time] => 0.004182
[connect_time] => 0.0057
[pretransfer_time] => 0.005737
[size_upload] => 0
[size_download] => 13458
[speed_download] => 872197
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => 0
[starttransfer_time] => 0.015135
[redirect_time] => 0
[redirect_url] => http://adsl.tci.ir/panel
[primary_ip] => 217.218.86.7
[certinfo] => Array ( )
[primary_port] => 80
[local_ip] => 185.208.174.63
[local_port] => 57646
)
更新了两个阵列的正则表达式模式
https://regex101.com/r/h1cm1z/2/
更新:根据第一个数组排序索引对第二个数组进行排序
new Date(Month Date Year)
答案 1 :(得分:12)
您可以将日期作为可排序的字符串进行排序。
要获得一个签名数组排序的多个数组,可以使用map排序,在其中对索引数组进行排序,指示最终排序,然后通过这种排序重新分配所有数组。
getD
函数通过获取索引array0
进行排序来返回格式化的字符串。在函数内部,字符串被分解为月份和年份部分,并由其ISO 8601表示形式代替。替换函数回调将获取匹配的项目,并返回带有格式的年份和对象的月份的数组,该对象具有月份名称和相关的月份编号。然后,该数组被连接并返回。
通过与String#localeCompare
进行比较来进行排序。
var array1 = ['Mar19', 'Apr18', 'Jun18', 'Jul18', 'May18', 'Jan19'],
array2 = ['Mar19_value', 'Apr18_value', 'Jun18_value', 'Jul18_value', 'May18_value', 'Jan19_value'],
array3 = ['55', '2', '3', '0', '21', '132'],
indices = Object
.keys(array1)
.sort(function (a, b) {
function getD(i) {
var months = { Jan: '01', Feb: '02', Mar: '03', Apr: '04', May: '05', Jun: '06', Jul: '07', Aug: '08', Sep: '09', Oct: '10', Nov: '11', Dec: '12' },
s = array1[i];
return s.replace(/^(...)(.+)$/, (_, m, y) => [y.padStart(4, '0'), months[m]].join('-'));
}
return getD(a).localeCompare(getD(b));
}),
result = [array1, array3].map(a => indices.map(i => a[i]));
result.forEach(a => console.log(...a));
答案 2 :(得分:10)
const input = ['Mar19', 'Apr18', 'Jun18', 'Jul18', 'May18', 'Jan19'];
//const output : ['Apr18','May18','Jun18','Jul18','Jan19','Mar19'];
//Can be done easily by using momentjs, darte-fns, but here i will do it natively
const t = {
Jan: 1,
Feb: 2,
Mar: 3,
Apr: 4,
May: 5,
Jun: 6,
Jul: 7,
Aug: 8,
Sep: 9,
Oct: 10,
Nov: 11,
Dec: 12
}
const giveConcatString = (a, t) => {
const monthPart = a.substr(0, 3)
const yearPart = a.substr(3)
return `${yearPart}${t[monthPart]}`
}
const sortedArray = input.sort((a, b) => {
const concatString = giveConcatString(a, t)
const concatStringB = giveConcatString(b, t)
return concatString <= concatStringB ? -1 : 1
})
console.log(sortedArray)
这可以帮助您解决此问题。是本地制作的。
答案 3 :(得分:10)
要正确订购,您需要知道月份的顺序。这不是按字母顺序排列的,因此您可以按月顺序使用数组,然后查找它们。
const monthOrder = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov' ,'Dec']
已经正确排序,可以与.indexOf()结合使用以获取一个月的排名。
const myArr = ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'];
const myArr2 = ['Mar19_value','Apr18_value','Jun18_value','Jul18_value','May18_value'
,'Jan19_value'];
const monthOrder = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
let sortYearMonth = (a, b) => {
let monthA = monthOrder.indexOf(a.slice(0,3))
let yearA = a.slice(3,6)
let monthB = monthOrder.indexOf(b.slice(0,3))
let yearB = b.slice(3,6)
return (`${yearA}-${monthA}` < `${yearB}-${monthB}`) ? -1 : (`${yearA}-${monthA}` > `${yearB}-${monthB}`) ? 1 : 0
}
let sortedMonths = myArr.sort(sortYearMonth)
let sortedMonths2 = myArr2.sort(sortYearMonth)
console.log(sortedMonths )
console.log(sortedMonths2 )
更新:位置相同的值
更新的版本将两个数组链接在一起,然后对第一个数组进行排序,同时保持相对位置到第二个数组。
想法:将两个数组与一个临时对象链接,然后使用Object.entries
提取键/值对。然后根据该对的第一个值(即array1的值)对数组进行排序。然后它以正确的顺序返回键/值对,您可以使用.map()
我在下面添加了一个基于字符串的示例和实际值示例的运行
const myArr = ['Mar19', 'Apr18', 'Jun18', 'Jul18', 'May18', 'Jan19'];
const myArr2 = ['Mar19_value', 'Apr18_value', 'Jun18_value', 'Jul18_value', 'May18_value', 'Jan19_value'];
const myArr3 = ['55','2','3','0','21','132'];
const monthOrder = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
let sortYearMonth = (a, b) => {
let monthA = monthOrder.indexOf(a.slice(0, 3))
let yearA = a.slice(3, 6)
let monthB = monthOrder.indexOf(b.slice(0, 3))
let yearB = b.slice(3, 6)
return (`${yearA}-${monthA}` < `${yearB}-${monthB}`) ? -1 : (`${yearA}-${monthA}` > `${yearB}-${monthB}`) ? 1 : 0
}
function sortByFirst(myArr, myArr2) {
let keyValue = myArr.reduce((links, item, i) => {
links[item] = myArr2[i];
return links
}, {})
let entries = Object.entries(keyValue)
return entries.sort((a, b) => sortYearMonth(a[0], b[0]))
}
let sortedEntries = sortByFirst(myArr, myArr2)
let sortedMonths = sortedEntries.map(i => i[0])
let sortedValues = sortedEntries.map(i => i[1])
let sortedEntries2 = sortByFirst(myArr, myArr3)
let sortedMonths2 = sortedEntries2.map(i => i[0])
let sortedValues2 = sortedEntries2.map(i => i[1])
console.log(sortedMonths)
console.log(sortedValues)
console.log(sortedMonths2)
console.log(sortedValues2)
答案 4 :(得分:5)
您可以尝试使用此原始代码段。
var MY = ['Mar19', 'Apr18', 'Jun18', 'Jul18', 'May18', 'Jan19'];
var s = "JanFebMarAprMayJunJulAugSepOctNovDec";
// converting to raw date format
for (i in MY) {
num = MY[i].match(/\d+/g);
letr = MY[i].match(/[a-zA-Z]+/g);
MY[i] = (s.indexOf(letr) / 3 + 1) + '-' + '20' + num;
}
// sorting logic
var sorted = MY.sort(function(a, b) {
a = a.split("-");
b = b.split("-")
return new Date(a[1], a[0], 1) - new Date(b[1], b[0], 1)
});
// converting back to original array after sorting
res = [];
for (i in sorted) {
var a = sorted[i].split('-');
res[i] = (s.substr((parseInt(a[0]) - 1) * 3, 3)) + '-' + a[1].substr(2, 2);
}
console.log(res);
答案 5 :(得分:3)
我使用lodash进行排序,并使用了substring
方法将日期划分为月和日部分
const data = ['Mar20','Mar21', 'Mar01', 'Mar19','Apr18','Jun18','Jul18','May18','Jan19']
const monthMap = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
const sorted = _.sortBy(data, date => monthMap.indexOf(date.substring(0,3)), date => date.substring(3,5))
console.log(sorted)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>
答案 6 :(得分:3)
let mth = ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'];
mth.sort((itemA, itemB)=>{
let mthAstr = itemA.slice(0,3)+" 01 "+itemA.slice(3,5);
let mthA = new Date(mthAstr);
let mthBstr = itemB.slice(0,3)+" 01 "+itemB.slice(3,5);
let mthB = new Date(mthBstr);
if (mthA < mthB)
return -1;
if (mthA > mthB)
return 1;
return 0;
});
答案 7 :(得分:3)
var Array = ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'];
Array.sort(function(a, b) {
a = [a.slice(0,3), ' 20', a.slice(3)].join('');
b = [b.slice(0,3), ' 20', b.slice(3)].join('')
return new Date() - new Date(b);
});
console.log(Array);
答案 8 :(得分:2)
我建议您的数据结构很不幸。使用共享索引要比组合它们的数据结构(例如,对象数组[{label: 'Mar19', value: 55}, ...]
)困难得多。
如果数据来自无法控制的上游解决方案,则仍可以在自己的工作中进行管理,在使用前进行转换。 (而且,如果您真的必须转换回去才能传递给他人。)
结合两个数组的函数的通用名称是zip
-就像拉链一样。此版本使用带有函数的函数来说明应如何组合配对的元素。 (在其他地方,此类功能可能称为zipWith
。)
此处sortArraysByDate
调用zip
传递了一个函数,该函数使用'Mar19'
从55
和{label: 'Mar19, value: 55, month: 'Mar', year: 19}
转换为dateFields
来提取月份和月份。该标签,然后使用简单的dateSort
const months = {Jan: 1, Feb: 2, Mar: 3, Apr: 4, May: 5, Jun: 6,
Jul: 7, Aug: 8, Sep: 9, Oct: 10, Nov: 11, Dec: 12}
const dateFields = (d) => ({
month: d.slice(0, 3),
year: Number(d.slice(3))
})
const dateSort = ({month: m1, year: y1}, {month: m2, year: y2}) =>
(y1 - y2) || (months[m1] - months[m2])
const zip = (fn, a1, a2) => a1.map((a, i) => fn(a, a2[i]))
const sortArraysByDate = (a1, a2) =>
zip((label, value) => ({label, value, ...dateFields(label)}), a1, a2)
.sort(dateSort)
.map(({label, value}) => ({label, value}))
const Array1 = ['Mar19','Apr18','Jun18','Jul18','May18','Jan19'];
const Array2 = ['55','2','3','0','21','132']; //real values
const result = sortArraysByDate(Array1, Array2)
console.log(result)
很有可能不需要map
中的sortArraysByDate
调用。没有它,结果数据将包含额外的year
和month
字段;可能不是问题。
如果您确实需要原始格式的那些更新的数组,则可以map
的结果:
const newArray1 = result.map(o => o.label)
const newArray2 = result.map(o => o.value)
但是,我强烈建议您除非绝对必要,否则不要这样做。这个结构真的很有用。配对的数组要少得多。
此外,如果您需要组合两个以上的数组,则可以编写稍微复杂一些的zip
版本:
const zip = (fn, ...as) => as[0].map((_, i) => fn(...as.map(a => a[i])))
这将在n
参数和n
数组上接受一个函数,并产生一个新的数组,其中包含分别在每个数组中的连续项上调用该函数的结果。