【问题标题】:Javascript merge and replace value by key on 2 array of objectsJavascript在2个对象数组上按键合并和替换值
【发布时间】:2020-07-22 08:16:34
【问题描述】:

我想在 Javascript 中合并 2 个对象数组,源数组类似于:

padding = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 0}]
data = [{'t': 3, 'c': 5}]

结果应该是这样的:

result = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 3}]

请注意,data 正在通过匹配 't' 填充到 padding。我尝试了各种方法,例如jQuery $.extend({}, padding, data),但输出不正确。

感谢您分享某些内容。谢谢。

编辑 1(2020 年 4 月 10 日)

正如@codemaniac 指出的那样,我有一个错字,结果应该是:

result = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 5}]

附加(2020 年 4 月 10 日)

我的padding 长度为1000,对于data,它应该是padding 的子集,键为't'

我正在寻找将data“合并”和“替换”成padding高效方式,有些人称之为“加法”,因为padding总是用@填充987654335@ 为每个对象。

如果可能的话,我不介意尝试lodash JS 实用程序。

【问题讨论】:

  • 怎么变成{'t': 3, 'c': 3}
  • 你是如何获得最终结果的?请正确举例说明问题:)
  • @CodeManiac 正如你所说,我已经更正了。
  • @YousufKhan 我在原帖中打错字了,我已经对帖子进行了编辑。
  • 好的,如果data = [{'t': 4, 'c': 5}]padding = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 0}],最终结果是什么?

标签: javascript arrays object merge lodash


【解决方案1】:

我假设您想要添加元素,以获得适当的元素大小(填充 + 宽度)

const padding = [{
  t: 1,
  c: 0,
}, {
  t: 2,
  c: 0,
}, {
  t: 3,
  c: 0,
}];

const data = [{
  t: 3,
  c: 5,
}];

// Use a reduce to build the new array
function mergeData(d1, d2) {
  return d2.reduce((tmp, x) => {
    // Check if the array already contains the key 't'
    const found = tmp.find(y => y.t === x.t);

    // If it does, add 'c' together
    if (found) {
      found.c += x.c;
    } else {
      // else, add the missing entry
      tmp.push(x);
    }

    return tmp;
  }, d1);
}

console.log(mergeData(data, padding));

【讨论】:

  • 谢谢。结果似乎没有排序。这个问题的目的是我想通过键“t”将“数据”中一些随机缺失的数据点与“填充”对齐,以便它们在图表上显得统一。
  • 我改用mergeData(padding, data)。我通过在mergeData 方法中切换参数使其工作。因此,接受的答案:)
【解决方案2】:

如果您希望合并数组,但还要在给定 t 值的情况下将来自padding 的对象替换为来自data 的对象,这是一种方法:

const padding = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 0}];
const data = [{'t': 3, 'c': 5}, {'t': 5, 'c': 6}];

const merged = [];

// loops through the objects in padding. If it finds an object in data that has the same t value, it chooses the object from data to add to the merged array. Otherwise, it uses the object from padding

padding.forEach((obj) => {
 	let dataObj = data.find(dataObj => dataObj.t === obj.t);
	if (dataObj) {
		merged.push(dataObj);
	} else {
		merged.push(obj);
	}
});

// loops through the data array. If there are any objects in data with a t value not in any padding object, it adds this to the merged array

data.forEach((obj) => {
	let paddingObj = padding.find(paddingObj => obj.t === paddingObj.t);
	if (!paddingObj) {
		merged.push(obj);
	}
});

console.log(merged);

【讨论】:

  • 感谢您加倍努力。我想我不需要“数据”循环。我想检查性能,我认为需要优化。 “数据”应该是“填充”的子集,但是通过“填充”循环似乎很浪费......“填充”的实际长度是1000
【解决方案3】:

您可以使用Mapmap

  • 首先使用 Map 以 t 为键,c 为值的数据构建一个 Map Object
  • 现在循环填充数组并查看是否存在 t 是 Map 我们使用来自 Map 的 c 的值,否则仅来自当前元素

const padding = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 0}];
const data = [{'t': 3, 'c': 5}];

const mapper = new Map(data.map(( { t, c } ) => [t, c] ));

const final = padding.map(({ t, c }) => ({
    t,
    c: mapper.has(t) ? mapper.get(t) : c
}));

console.log(final);

【讨论】:

  • 如果我把所有格式都改成数组,不是更简单吗? padding = [[1, 0], [2, 0], [3, 0]]data = [[3, 5]] 得到result = [[1, 0], [2, 0], [3, 5]]
【解决方案4】:

我不确定效率,但这段代码有效并且可读性很好

var padding = [{'t': 1, 'c': 0}, {'t': 2, 'c': 0}, {'t': 3, 'c': 0}]
var data = [{'t': 3, 'c': 5}, {'t': 4, 'c': 5}]

data.forEach(d => {
    padding.find(p => p.t === d.t).c = d.c
})

console.log(padding)
// OUTPUT: [ { t: 1, c: 0 }, { t: 2, c: 0 }, { t: 3, c: 5 } ]

【讨论】:

    猜你喜欢
    • 2019-09-04
    • 2013-06-11
    • 1970-01-01
    • 2015-03-31
    • 1970-01-01
    • 2019-03-13
    • 2011-10-29
    • 2015-12-05
    • 2017-02-18
    相关资源
    最近更新 更多