Я бы предположил, что ваша структура данных неудачна. Работа с общими индексами делает это намного сложнее, чем структура данных, которая их объединяет, например, массив объектов [{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
массивов и выдает новый массив, содержащий результат вызова этой функции соответственно для последовательных элементов в каждом из массивов.