基于匹配键合并两个多维数组?

时间:2017-02-24 19:25:47

标签: javascript arrays json multidimensional-array

所以目前我正在生成应该组合在一起形成以下JSON的记录:

{
  "Monday": [{
      "Index": "1",
      "To": "200",
      "From": "1200"
    },
    {
      "Index": "2",
      "To": "1300",
      "From": "1400"
    }
  ],
  "Tuesday": [{
      "Index": "1",
      "To": "100",
      "From": "200"
    },
    {
      "Index": "2",
      "To": "1000",
      "From": "1200"
    },
    {
      "Index": "3",
      "To": "1300",
      "From": "1500"
    }
  ]
}

但目前,输出看起来更像是这样:

正如您所看到的,正在创建两个共享相同“索引”值的记录 - 这主要是因为我还没有弄清楚如何使用where index = <index> insert来处理查找具有匹配索引的记录并添加它的属性。

目前,代码看起来像这样 -

var controlsJson;
//Assume two loops are running through different sets of values for "type". setting them to "To" and "From" pragmatically.
//Array building
if (controlsJson == null) {
  controlsJson = [];
}
if (controlsJson[date] == null) {
  controlsJson[date] = [];
}
var pusher = [];
pusher["Index"] = index;
pusher[type] = time;
controlsJson[date].push(pusher);

除了通过匹配索引键解决问题外,还有其他方法可以改善这一点吗?

3 个答案:

答案 0 :(得分:1)

如果您使用以下格式表示数据,这将更容易遍历:

let state = {
  Monday: {
    1: {
      To: 200,
      From: 1200
    },
    2: {
      To: 1300,
      From: 1400
    }
  },
  Tuesday: {
    1: {
      To: 100,
      From: 200
    },
    2: {
      To: 1000,
      From: 1200
    },
    3: {
      To: 1300,
      From: 1500
    }
  }
}

state = { ...state, Tuesday: { ...state.Tuesday, 2: { To: 1500, From: 1400 } } }

console.log(state)

如果您不关心不变性,以下内容也适用:

let state = {
  Monday: {
    1: {
      To: 200,
      From: 1200
    },
    2: {
      To: 1300,
      From: 1400
    }
  },
  Tuesday: {
    1: {
      To: 100,
      From: 200
    },
    2: {
      To: 1000,
      From: 1200
    },
    3: {
      To: 1300,
      From: 1500
    }
  }
}

state["Tuesday"][2] = { To: 1500, From: 1400 };

console.log(state)

答案 1 :(得分:0)

如果每天索引都以0开头,那么这个小片段应该可以解决问题:

// your object that you start with
var days = {
    'Monday': [
        {Index: 0, Start: 330},
        {Index: 0, End: 1330},
        {Index: 1, Start: 330},
        {Index: 1, End: 1330},
        {Index: 2, Start: 330},
        {Index: 2, End: 1330},
    ],
    'Tuesday': [
        {Index: 0, Start: 330},
        {Index: 0, End: 1330},
        {Index: 1, Start: 330},
        {Index: 1, End: 1330},
        {Index: 2, Start: 330},
        {Index: 2, End: 1330},
        {Index: 3, Start: 330},
        {Index: 3, End: 1330},
    ],
};

// create an array of indexes. For each index, filter days by that Index,
// then pass those to Object.assign to merge the 2 items together.
var i, dayMaxIndex;
for (i in days) {
    if (days.hasOwnProperty(i)) {
        dayMaxIndex = Math.max.apply(null, days[i].map(function(d) { return d.Index; }));
        days[i] = Array.from({length: dayMaxIndex+1}, (v, i) => i).map(function(d) {
            return Object.assign.apply(null, days[i].filter(function(day) {
                return day.Index == d;
            }));
        });
    }
}
console.log(days);

您可以更多地了解Object.assign here

我发现这件作品有点令人困惑:

Array.from({length: dayMaxIndex+1}, (v, i) => i)

它生成一个序列号数组,从0开始,以dayMaxIndex结束。 Here's我找到了这个例子。

答案 2 :(得分:0)

正如 cchamberlain 指出的那样,我正在以比实际需要更复杂的方式接近索引。

我将我的代码修改为以下内容并使用不可变的方法(我认为这就是它的名称),只需使用索引即可实际添加记录!

//Array building
if (controlsJson == null) {
    controlsJson = [];
}
if (controlsJson[date] == null) {
    controlsJson[date] = [];
}

if (controlsJson[date][index] == null) {
    controlsJson[date][index] = [];
}

controlsJson[date][index][type] = time;
}

另请注意,如果您希望使用JSON.Stringify,则需要将= []更改为= {}

再次 - 如果你跌倒了我可以进一步改进这段代码,请告诉我。