【问题标题】:How to find indexes of nested array elements based on id?如何根据 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 )。出于某种原因,我无法让它正常工作。任何帮助将不胜感激。

【问题讨论】:

  • 为什么不获取三个索引,因为三个嵌套数组?

标签: javascript arrays vue.js object multidimensional-array


【解决方案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 提供了一个相当简洁易读的解决方案,尽管在下面的示例中,它要求结构保持静态,因为它专门引用了 leftColrightCol。您可以通过将解构替换为 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);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-06-21
        • 1970-01-01
        相关资源
        最近更新 更多