如何根据 id 查找嵌套数组元素的索引?
Posted
技术标签:
【中文标题】如何根据 id 查找嵌套数组元素的索引?【英文标题】:How to find indexes of nested array elements based on id? 【发布时间】:2021-01-11 15:01:38 【问题描述】:所以我有一个嵌套的对象数组,其结构如下:
let pages = [
[
leftCol: [
height: 34, id: 10 ,
height: 18, id: 20 ,
height: 45, id: 30 ,
height: 59, id: 40 ,
],
,
rightCol: [
height: 34, id: 50 ,
height: 34, id: 60 ,
height: 34, id: 70 ,
],
,
],
[
leftCol: [
height: 34, id: 80 ,
height: 18, id: 90 ,
height: 45, id: 100 ,
height: 59, id: 110 ,
],
,
rightCol: [
height: 34, id: 120 ,
height: 34, id: 130 ,
height: 34, id: 140 ,
],
,
],
];
现在我想创建一个方法,该方法可以基于作为参数给出的id
返回元素的索引,并返回外部元素的索引。例如:
findIdx(pages, 30)
将返回元素 (2) 的 idx 以及外部数组 (0) 的 idx。
findIdx(pages, 110)
将返回元素 (3) 的 idx 以及外部数组 (1) 的 idx。
我能想到的最好的方法是:
function getIdxAndPageNumOfColumn(array, columnIdx, payloadId)
let idx;
let pageNum;
for (pageNum = 0; pageNum < array.length; pageNum++)
let leftCol = array[pageNum][0].leftCol;
let rightCol = array[pageNum][1].rightCol;
let column = columnIdx === 0 ? leftCol : rightCol;
idx = column.findIndex(item => item.id == payloadId);
if (idx > -1) break;
return
idx: idx,
pageNum: pageNum,
;
但这需要我指定 columnIdx
作为参数(0 的 columnIdx
将始终等于 pages 数组中的 leftCol
,而 1 的 columnIdx
将等于 rightCol
)。出于某种原因,我无法让它正常工作。任何帮助将不胜感激。
【问题讨论】:
为什么不获取三个索引,因为三个嵌套数组? 【参考方案1】:您可以采用动态方法获取所需对象的所有索引。
function findIdx(array, id)
function find(array)
if (!array) return;
let inner,
index = array.findIndex(o =>
if (o.id === id) return true;
if (Array.isArray(o)) return inner = find(o);
return inner = find(o.leftCol || o.rightCol);
);
return index !== -1 && [index, ...(inner || [])];
return find(array);
let pages = [[ leftCol: [ height: 34, id: 10 , height: 18, id: 20 , height: 45, id: 30 , height: 59, id: 40 ] , rightCol: [ height: 34, id: 50 , height: 34, id: 60 , height: 34, id: 70 ] ], [ leftCol: [ height: 34, id: 80 , height: 18, id: 90 , height: 45, id: 100 , height: 59, id: 110 ] , rightCol: [ height: 34, id: 120 , height: 34, id: 130 , height: 34, id: 140 ] ]];
console.log(findIdx(pages, 30)); // [0, 0, 2]
console.log(findIdx(pages, 110)); // [1, 0, 3]
【讨论】:
【参考方案2】:reducer 提供了一个相当简洁易读的解决方案,尽管在下面的示例中,它要求结构保持静态,因为它专门引用了 leftCol
和 rightCol
。您可以通过将解构替换为 Object.entries()
循环来使其更通用。
直接解构页面对象
let pages = [ [ leftCol: [ height: 34, id: 10 , height: 18, id: 20 , height: 45, id: 30 , height: 59, id: 40 , ], , rightCol: [ height: 34, id: 50 , height: 34, id: 60 , height: 34, id: 70 , ], , ], [ leftCol: [ height: 34, id: 80 , height: 18, id: 90 , height: 45, id: 100 , height: 59, id: 110 , ], , rightCol: [ height: 34, id: 120 , height: 34, id: 130 , height: 34, id: 140 , ], , ],];
function getIdxAndPageNumOfColumn(array, payloadId)
const pageAndIndex = array.reduce((acc, [leftCol, rightCol], i) =>
if ((leftMatch = leftCol.findIndex(p => p.id === payloadId)) !== -1)
acc['idx'] = leftMatch;
acc['pageNum'] = i;
acc['colIdx'] = 0;
else if ((rightMatch = rightCol.findIndex(p => p.id === payloadId)) !== -1)
acc[idx] = rightMatch;
acc['pageNum'] = i;
acc['colIdx'] = 1;
return acc
,)
return pageAndIndex;
console.log(getIdxAndPageNumOfColumn(pages, 30));
console.log(getIdxAndPageNumOfColumn(pages, 110));
使用 Object.values
let pages = [[ leftCol: [ height: 34, id: 10 , height: 18, id: 20 , height: 45, id: 30 , height: 59, id: 40 ,], , rightCol: [ height: 34, id: 50 , height: 34, id: 60 , height: 34, id: 70 ,], ,], [ leftCol: [ height: 34, id: 80 , height: 18, id: 90 , height: 45, id: 100 , height: 59, id: 110 ,], , rightCol: [ height: 34, id: 120 , height: 34, id: 130 , height: 34, id: 140 ,], ,],];
function getIdxAndPageNumOfColumn(array, payloadId)
const pageAndIndex = array.reduce((acc, pArr, pi) =>
pArr.forEach((col, ci) =>
Object.values(col).forEach(v =>
if ((match = v.findIndex(p => p.id === payloadId)) !== -1)
acc['idx'] = match;
acc['pageNum'] = pi;
acc['colIdx'] = ci;
);
);
return acc
, );
return pageAndIndex;
console.log(getIdxAndPageNumOfColumn(pages, 30));
console.log(getIdxAndPageNumOfColumn(pages, 110));
【讨论】:
谢谢。我已经尝试了所有方法,你的方法似乎效果最好。不敢相信我有多么挣扎嘿嘿。干杯:)。【参考方案3】:试试:
const findPage = (pages, pageid) =>
new Promise((res) =>
pages.map((page) =>
page.map((p) =>
Object.entries(p).map(([k, v]) =>
const x = v.filter((_) => _.id === pageid);
if (x.length > 0)
res(x["0"]);
);
);
);
);
findPage(pages, idWhichYouSearch).then(console.log);
【讨论】:
【参考方案4】:你来了。
function findIdx(pages, id)
for (let index = 0; index < pages.length; index++)
const cols = pages[index];
for (const e of cols)
for (const key in e)
const item = e[key].find((a) => a.id == id);
if (item) return index;
const item = findIdx(pages, 110);
console.log(item);
【讨论】:
以上是关于如何根据 id 查找嵌套数组元素的索引?的主要内容,如果未能解决你的问题,请参考以下文章