Javascript 展平元素后,将其索引保留在嵌套数组中

Javascript 展平元素后,将其索引保留在嵌套数组中,javascript,arrays,dictionary,multidimensional-array,Javascript,Arrays,Dictionary,Multidimensional Array,我有一个单层嵌套数组,如下所示 var nestedArrays = [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]; 我使用函数将其展平为单个统一数组(,并且比通常的reduce/concat更快,由于兼容性问题,无法使用native flat()): 现在假设,我有值“3”,我希望从nestedArray中找到它来自哪个数组。(例如,在“3”的情况下,返回值“0”,因为它来自嵌套数组中的第0个元素数组)。我该如何以最简单或最有效的方式进行此操作? 我尝试了几种方法

我有一个单层嵌套数组,如下所示

var nestedArrays = [[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]];
我使用函数将其展平为单个统一数组(,并且比通常的reduce/concat更快,由于兼容性问题,无法使用native flat()):

现在假设,我有值“3”,我希望从nestedArray中找到它来自哪个数组。(例如,在“3”的情况下,返回值“0”,因为它来自嵌套数组中的第0个元素数组)。我该如何以最简单或最有效的方式进行此操作?

我尝试了几种方法来实现这一点,例如:

1) 将现有嵌套数组转换为包含值本身和父数组中嵌套数组索引的每个嵌套值的一对值。简单但重复的数据,创建中间数组和额外的forEach循环:

var nestedArrays2 = [[0,0],[1,0],[2,0],[3,0],[4,1],[5,1],[6,1],[7,2],[8,2],[9,2]];
然后,同样将其展平,但这将导致:

[0,0,1,0,2,0,3,0,4,1,5,1,6,1,7,2,8,2,9,2]
也可以对奇数值进行过滤,总之:

merged = flatten(nestedArrays2).filter((num, index) => {
  return index % 2 !== 0;
})
因此,在本例中,我知道
nestedArrays2[merged[I]][1]
将返回原始嵌套数组的索引,
merged[I]
处的值与
nestedArrays
中的值相同

1a)与前一个阵列不同,但总体思路相同,可以创建一个单独的阵列,而无需更改原始的
嵌套阵列
。既然我们已经在循环它了,我们不妨在同一次迭代中花点时间将它展平

var merged = [];
var nestIndexes = [];
nestedArrays.forEach((element,index){
  element.forEach((e) {
    merged.push(e);
    nestIndexes.push(index);
  });
});
这将导致合并索引和嵌套索引,如下所示:

merged [0,1,2,3,4,5,6,7,8,9]
nestedIndexes [0,0,0,0,1,1,1,3,3,3]
因此,如果我在
merged
中获得某个值的
索引
,我可以立即从
nestedindex
nestedindex[index]

2) 保留单独的索引引用数组

我在想,在合并嵌套数组之前,也许我可以保留一个单独的数组来标记嵌套数组开始的索引位置。只需循环通过
nestedarray
,获取每个元素的
length
,并将其添加到上一个值中,使其累积:

var nestPositions = [];
nestedArrays.forEach((element, index) {
  nestPositions[index] = (element.length + (nestedArrays[index - 1] || 0) -1); //for when index is 0
})
因此,我们的立场将是:

[3,6,9]
nestedarray
中每个嵌套数组中最后一个元素的索引

nestMap = new Map();
nestedArrays.forEach((element, index) => {
  nestMap.set(index, element);
})
但在这种情况下,在我得到
merged[I]
之后,我每次都必须在nestPositions数组上循环,以查看每个元素是否小于或等于I和break

3) 从
nestedarray
创建具有嵌套数组索引的映射

nestMap = new Map();
nestedArrays.forEach((element, index) => {
  nestMap.set(index, element);
})
然后,我可以像正常情况一样进行合并,为了从
merged[I]
中获取元素的嵌套数组索引,我可以假设,在映射上执行forEach,如下所示:

nestMap.forEach((value, key) => {
  if (value.includes(merged[i]) return key;
}

不管怎么说,这就是我脑子里能想到的方法。哪一个是最好的,有没有更好更简洁的方法来处理这个问题?无论是哪种方式,感谢任何帮助,甚至只是为了达到这一部分哈哈。

地图上执行
forEach
,都会违背使用
地图的目的。但是,如果您创建一个从元素值到其数组索引的
映射,您可以直接使用
Map.get(value)

var nestedarray=[[0,1,2,3]、[4,5,6]、[7,8,9];
合并风险值=[0,1,2,3,4,5,6,7,8,9];
var nestedIndex=新映射();
nestedArray.forEach((嵌套,i)=>{
nested.forEach((element,j)=>nestedIndex.set(element,i));
});
log(nestedIndex.get(merged[0]);
log(nestedIndex.get(merged[3]);
log(nestedIndex.get(merged[5]);

log(nestedIndex.get(merged[9])啊,好点!但是为什么不简单地创建一个数组而不是映射,
var nestedIndex=[];nestedArray.forEach((nested,i)=>{nested.forEach((element)=>nestedIndex.push(i));})?然后,
console.log(nestedIndex[i])
将给出合并的[i]?@Terrornado的nestedIndex,它假定数组元素以完美的顺序排列。如果你的元素值是50,70,100…?我不知道你的意思,为什么嵌套数组中的值很重要?但是,如果在创建nestedIndex后以某种方式交换nestedArray或nestedIndex,则是的,因为它们不是关系型的,因此不会反映其他实时性。但对于一个临时中介来说应该是好的,我认为它不会有任何其他的操作。但我想我在这里遗漏了什么…@Terrornado啊,我现在明白你的意思了。那也行。但是你必须知道
i
。假设您只知道元素值。您必须首先在merged中计算它的索引,然后才能得到值
nestedIndex[i]
nestMap.forEach((value, key) => {
  if (value.includes(merged[i]) return key;
}