You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何移除多维数组中的双引号以适配moment.js时间选择器?

问题背景与尝试
  • 之前找到过类似问题,但给出的解决方案会将字符串转换为数字,不符合需求。
  • 需要移除双引号是为了符合moment.js语法规范,以此配置时间选择器的禁用时段。
  • 尝试过从后端PHP代码移除双引号,未生效,接受JavaScript或PHP任一解决方案。
  • 试过以下JavaScript代码,但结果仍保留双引号:
const timeIntervalsData = [
  [
    "moment({ hour:6, minute:45 }), moment({ hour:7, minute:45 })",
  ],
  [
    "moment({ hour:10, minute:30 }), moment({ hour:11, minute:30 })",
  ],
]

let string = JSON.stringify(timeIntervalsData)
string.replace (/"/g,'')

实际业务代码

前端将多维数组用于时间选择器的配置:

const timeIntervalsData = []

// `timeIntervalsData` 存储后端接口返回的响应数据

$.ajax({
    type: 'POST',
    url: 'call-url-of-backend',
    data: {_token: CSRF_TOKEN},
    dataType: 'JSON',
    success: function (data) {
        if (data.status == true) {
            timeIntervalsData = data.time
        }
    },error: function(xhr, status, error) {
        var r = jQuery.parseJSON(xhr.responseText)
        console.log(r.message)
    }
})

let options = {
    format: 'hh:mm A',
    // 此处加载多维数组
    disabledTimeIntervals: timeIntervalsData,

    // 官方示例语法
    disabledTimeIntervals: [
        [moment({ hour:6, minute:45 }), moment({ hour:7, minute:45 })],
        [moment({ hour:10, minute:30 }), moment({ hour:11, minute:30 })],
    ],
}

$('.datetimepicker').datetimepicker(options)

后端PHP代码

当前后端生成数据的代码:

$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
    ->whereBelongsTo($user)
    ->where('weekday', 1)
    ->get()
    ->toArray();

$collection = collect($schedules)->map(function ($time) {
    return [date("g:i", strtotime($time['start_time'])), date("g:i", strtotime($time['end_time']))];
});

$data = $collection->values()->all();

$carrier = [];

foreach ($data as $key => $a) {
  $detail1 = preg_split('/:/i', $a[0]);
  $detail2 = preg_split('/:/i', $a[1]);

  // 尝试用str_replace移除双引号
  array_push($carrier, array(str_replace('"', "", 'moment({ hour:'.$detail1[0].', minute:'.$detail1[1].' }), moment({ hour:'.$detail2[0].', minute:'.$detail2[1].' })')));
}

return response()->json([
    'status' => true,
    'time' => $carrier,
], 200);

// `$carrier` 输出结果
[
  [
    "moment({ hour:6, minute:45 }), moment({ hour:7, minute:45 })",
  ],
  [
    "moment({ hour:10, minute:30 }), moment({ hour:11, minute:30 })",
  ],
]

测试情况

编辑:测试代码结果

尝试以下代码后,控制台输出不符合预期:

const timeIntervalsData = JSON.stringify({
    moments: [
        { hour: 6, minute: 45 }, { hour: 7, minute: 45 },
        { hour: 10, minute: 30 }, { hour: 11, minute: 30 }
    ]
});

let options = {
    format: 'hh:mm A',
    disabledTimeIntervals: [
        JSON.parse(timeIntervalsData).moments.forEach( interval => moment(interval) )
    ],
}

console.log(options)

(控制台输出中disabledTimeIntervals为[undefined])

编辑2:测试更新后的代码结果

调整代码后,disabledTimeIntervals将所有moment实例合并为单个数组,仅前两个时段生效:

const timeIntervalsData = JSON.stringify( { moments: [ 
  { hour: 6, minute: 45 }, { hour: 7, minute: 45 },
  { hour: 10, minute: 30 }, { hour: 11, minute: 30 } ] 
});

JSON.parse(timeIntervalsData).moments.forEach( interval => 
  console.log(moment(interval)) );

let options = {
    format: 'hh:mm A',
    disabledTimeIntervals: [
        JSON.parse(timeIntervalsData).moments.map( interval => moment(interval) )
    ],
}

console.log(options);

输出结果:

disabledTimeIntervals: [
    [M, M, M, M] // 合并为单个数组,仅前两个时段生效
],

而正确格式应为:

disabledTimeIntervals: [
    [moment({ hour:6, minute:45 }), moment({ hour:7, minute:45 })],
    [moment({ hour:10, minute:30 }), moment({ hour:11, minute:30 })]
],

解决方案

方案1:后端PHP调整数据格式(推荐)

不要将moment代码字符串化,直接返回小时和分钟的结构化数据,由前端生成moment实例:

$user = User::find(1);
$schedules = Schedule::select('start_time', 'end_time')
    ->whereBelongsTo($user)
    ->where('weekday', 1)
    ->get()
    ->toArray();

// 生成包含时段的结构化数组
$carrier = collect($schedules)->map(function ($time) {
    $start = date("H:i", strtotime($time['start_time']));
    $end = date("H:i", strtotime($time['end_time']));
    list($startHour, $startMin) = explode(':', $start);
    list($endHour, $endMin) = explode(':', $end);
    return [
        ['hour' => (int)$startHour, 'minute' => (int)$startMin],
        ['hour' => (int)$endHour, 'minute' => (int)$endMin]
    ];
})->values()->all();

return response()->json([
    'status' => true,
    'time' => $carrier,
], 200);

后端返回的数据格式为:

{
  "status": true,
  "time": [
    [{"hour":6,"minute":45},{"hour":7,"minute":45}],
    [{"hour":10,"minute":30},{"hour":11,"minute":30}]
  ]
}

方案2:前端JS处理数据

拿到后端返回的数据后,解析生成符合要求的moment数组:

$.ajax({
    type: 'POST',
    url: 'call-url-of-backend',
    data: {_token: CSRF_TOKEN},
    dataType: 'JSON',
    success: function (data) {
        if (data.status == true) {
            // 处理后端返回的字符串数据,转成moment数组
            const disabledIntervals = data.time.map(intervalStrArr => {
                const momentStrs = intervalStrArr[0].split(', ');
                return momentStrs.map(momentStr => {
                    const hourMatch = momentStr.match(/hour:(\d+)/);
                    const minuteMatch = momentStr.match(/minute:(\d+)/);
                    return moment({ 
                        hour: parseInt(hourMatch[1]), 
                        minute: parseInt(minuteMatch[1]) 
                    });
                });
            });
            
            // 初始化时间选择器
            $('.datetimepicker').datetimepicker({
                format: 'hh:mm A',
                disabledTimeIntervals: disabledIntervals
            });
        }
    },error: function(xhr, status, error) {
        var r = jQuery.parseJSON(xhr.responseText)
        console.log(r.message)
    }
})

此方式无需修改后端,直接在前端解析字符串生成moment实例,最终得到[[M, M], [M, M]]的正确格式。

内容的提问来源于stack exchange,提问作者Lucky Person

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 08:55:16