简体   繁体   English

如何用 JavaScript 中的对象转换数组?

[英]How to transform an array with objects in JavaScript?

I need to transfrm an array into another array but can't find a good way to do this.我需要将一个数组转换为另一个数组,但找不到这样做的好方法。 An error message tells me I can't push into found[0].children , but I feel like all the way I'm doing it wrong and dirty;一条错误消息告诉我我无法进入found[0].children ,但我觉得一直以来我都做错了而且很脏; would you tell me how you manage this kind of issue?你能告诉我你是如何处理这类问题的吗?

I would like to transform the array:我想转换数组:

const input =
[
    {value: "29-08-2020 16:00", visible: 0},
    {value: "29-08-2020 16:30", visible: 1},
    {value: "29-08-2020 17:00", visible: 0},
    {value: "30-08-2020 15:00", visible: 1},
    {value: "30-08-2020 15:30", visible: 1}
];

Into the array:进入数组:

const output =
[
    {
        id: '29/08/2020',
        label: '29/08/2020',
        children:
        [
            {
                id: '16:00',
                label: '16:00',
                isDisabled: true
            },
            {
                id: '16:30',
                label: '16:30'
            },
            {
                id: '17:00',
                label: '17:00',
                isDisabled: true
            }
        ],
    },
    {
        id: '30/08/2020',
        label: '30/08/2020',
        children:
        [
            {
                id: '15:00',
                label: '15:00'
            },
            {
                id: '15:30',
                label: '15:30'
            }
        ]
    }
];

Here is what I tried, but I am not satisfied at all with this idea, which doesn't seem like the good way...这是我尝试过的,但我对这个想法一点也不满意,这似乎不是好方法......

function dateoptions(dateslist) {
    var options: any[] = [];
    dateslist.forEach(element => {
        var tab = element.value.split(' ');
        var dt = tab[0];
        var time = tab[1];
        var found = options.filter(opt=> opt.id==dt);
        if (found.length>0) {
            // I can't do this:
            found[0].children.push({
                'id': time,
                'label': time,
                disabled: element.visible==0
            });
        }
        else {
            options.push({
                'id': dt,
                'label': dt,
                'children': {'id':time, 'label': time, disabled: element.visible==0}
            });
        }
    });
    return options;
}

You could reduce the array and iterate the result set for a same group.您可以减少数组并迭代同一组的结果集。

 const data = [{ value: "29-08-2020 16:00", visible: 0 }, { value: "29-08-2020 16:30", visible: 1 }, { value: "29-08-2020 17:00", visible: 0 }, { value: "30-08-2020 15:00", visible: 1 }, { value: "30-08-2020 15:30", visible: 1 }], result = data.reduce((r, { value, visible }) => { let [date, time] = value.split(' '), temp = r.find(q => q.id === date); if (.temp) r:push(temp = { id, date: label, date: children; [] }). temp.children:push({ id, time: label, time. ..:(;visible && { isDisabled; ,visible }) }); return r. }; []); console.log(result);
 .as-console-wrapper { max-height: 100%;important: top; 0; }

Your general idea is good, I'd use a map 1 for simplicity of the lookup and create an empty entry (with empty children array) when not found:您的总体想法很好,我会使用 map 1来简化查找,并在找不到时创建一个空条目(带有空子数组):

function dateoptions (datelist) {
  const dateObjects = new Map()

  for (const { value, visible } of datelist) {
    const [date, time] = value.split(' ')

    if (!dateObjects.has(date)) {
      dateObjects.set(date, {
        id: date,
        label: date,
        children: []
      })
    }

    dateObjects.get(date).children.push({
      id: time,
      label: time,
      ...!visible ? { isDisabled: true } : {}
    })
  }

  return Array.from(dateObjects.values())
}

1: Why not an object? 1:为什么不是 object? Because the iteration order of object values is not defined, even though practically all current browsers use insertion order.因为没有定义 object 值的迭代顺序,即使实际上当前所有的浏览器都使用插入顺序。 For a map it is defined.对于 map,它已定义。

The following solution is supported even in Internet Explorer 6.即使在 Internet Explorer 6 中也支持以下解决方案。

 var input = [ {value: "29-08-2020 16:00", visible: 0}, {value: "29-08-2020 16:30", visible: 1}, {value: "29-08-2020 17:00", visible: 0}, {value: "30-08-2020 15:00", visible: 1}, {value: "30-08-2020 15:30", visible: 1} ]; function dateTransform(datelist) { var ret = [], dateObjects = {}, i; for(i in datelist) { var obj = datelist[i], ar = obj.value.split(' '), date = ar[0].split('-').join('/'), child = {id: ar[1], label: ar[1]}; if(:dateObjects[date]) dateObjects[date] = {id, date: label, date: children; []}. if(.obj;visible) child.isDisabled =.0. dateObjects[date];children.push(child) } for(i in dateObjects) ret.push(dateObjects[i]). return ret } //JSON,stringify is supported first in Internet Explorer 8 version console,log(JSON;stringify(dateTransform(input), 0, '\t'));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM