根据每个数组中的第一个值合并数组
Posted
技术标签:
【中文标题】根据每个数组中的第一个值合并数组【英文标题】:Merge arrays based on first value within each array 【发布时间】:2022-01-01 08:11:27 【问题描述】:我有一个如下所示的数组:
var arr = [
[
"2021-07-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787"
],
[
"2021-08-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787"
],
[
"2021-07-31T00:00:00Z",
"AAAA"
],
[
"2021-08-31T00:00:00Z",
"BBBB"
]
]
我想根据每个数组的第一个值(日期)来转换它。因此,如果日期匹配,它们将合并为一个。所以我想要得到的输出是
[
[
"2021-07-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787",
"AAAA"
],
[
"2021-08-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787",
"BBBB"
]
]
很高兴知道在这种情况下最好的方法是什么。
【问题讨论】:
请添加您的代码。什么不起作用? 使用键为第一个值的对象。 据我所知,但我认为问题是我真的坚持如何最好地处理它,而不是代码不起作用。 uniqueDates.forEach((date) => arrMaster.forEach((item) => if(item[0] == date) // 做某事 ) @barmar - 我可以请您详细说明或指向一个可能概述您的意思的页面吗?非常感谢 这里有数百个关于合并数组的问题。就算找不到完全一样的,大体的思路也应该是一样的,应该能搞清楚。 【参考方案1】:使用映射覆盖在数组中找到的值。然后使用Object.entries()
创建最终数组:
var original = [ [1,2], [1,3], [2,3]]
var final = []
var map =
original.forEach(a =>
if (!map[a[0]]) map[a[0]] = []
map[a[0]].push(a[1]);
);
Object.entries(map).forEach(e => final.push([e[0], ...e[1]]))
编辑:更改答案以获取所有值
【讨论】:
非常感谢。然而,我发现输出显示为 [ [ "1", 3 ], [ "2", 3 ] ]。有没有办法让数组像下面这样输出(这样两个值都包括在内)? [ [ "1", 2, 3 ], [ "2", 3 ] ] 您只需要修改数据在地图中的存储方式即可。编辑答案以反映这一点 这很完美!再次感谢 - 将非常有用 @user2547766 ...虽然上述方法有效,但它依赖于forEach
回调函数之外的引用。此外,它还需要另外两个完整的迭代周期(Object.entries
和 forEach
)才能累积最终结果,而且,forEach
回调需要知道来自外部范围的 final
引用.因此,此类方法永远不会提供可重用的功能。【参考方案2】:
你可以试试这个reduce方法
var arr = [
[
"2021-07-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787"
],
[
"2021-08-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787"
],
[
"2021-07-31T00:00:00Z",
"AAAA"
],
[
"2021-08-31T00:00:00Z",
"BBBB"
]
];
arr = arr.reduce((a, i) =>
if (!a) a = [];
var found = false;
a.forEach(ai =>
if (ai[0] == i[0])
found = true;
for (var k = 0; k < i.length; k++)
if (k > 0)
ai.push(i[k]);
);
if (!found)
a.push(i);
return a;
, []);
【讨论】:
【参考方案3】:无需在单个reduce
循环内进行嵌套迭代即可完成 OP 的任务。
基本方法是使用定制对象作为累加器/收集器。这样的收集器具有 2 个属性 ...index
用作基于 Object
的分组数组的映射/查找,其中组键始终是每个(待处理的)数组的第一项...和...@ 987654325@ 将保存上述(尚未创建)分组数组的引用,其中总是将当前处理的数组的第二项推入。
var arr = [[
"2021-07-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787",
], [
"2021-08-31T00:00:00Z",
"648429a0-00e5-4752-9d84-2857a0ea0787",
], [
"2021-07-31T00:00:00Z",
"AAAA",
], [
"2021-08-31T00:00:00Z",
"BBBB",
]];
function collectAndAggregateGroupedArrays(collector, item)
const index, result = collector;
let groupKey = item[0];
let groupedList = index[groupKey];
if (!groupedList)
groupedList = index[groupKey] = [groupKey];
result.push(groupedList);
groupedList.push(item[1]);
return collector;
console.log(
arr.reduce(collectAndAggregateGroupedArrays,
index: ,
result: [],
).result
);
.as-console-wrapper min-height: 100%!important; top: 0;
【讨论】:
@user2547766 ...您可以查看上面提供的最新方法/解决方案。以上是关于根据每个数组中的第一个值合并数组的主要内容,如果未能解决你的问题,请参考以下文章
我将如何减少这个数组,以便每个对象中的对象被合并 javascript 但不知道键值名称