【问题标题】:Find index in two dimensional array在二维数组中查找索引
【发布时间】:2016-10-26 10:17:33
【问题描述】:

如果我有一个包含对象的数组,其中每个对象都有一个 id 属性,我可以使用以下方法找到一个索引:

data.findIndex(x=>x.id === newData.id);

但是如果 data 是一个对象数组呢?有没有一种很好的方法来获取这个数据结构的两个索引?所以data.findIndex 会以某种方便的形式返回ij

【问题讨论】:

标签: javascript arrays ecmascript-6


【解决方案1】:

如果 findIndex 是一个值数组,您可以在 findIndex 中使用 Array.includes

var data = [
  [1,2,3],
  [4,5,6],
  [7,8,9]
]
var searchParam = 8;
var index = data.findIndex(x=>x.includes(searchParam))
console.log(index)

如果是更深层次的对象数组,可以使用递归。

var data = [
  [{id: 1},{id: 2},{id: 3}],
  [{id: 4},{id: 5},{id: 6}],
  [{id: 7},{id: 8},{id: 9}]
]
var searchValue = 8;
var index = data.findIndex(x=>{
  return searchInObject(x, searchValue);
})

function searchInObject(obj, searchValue){
  var _s = JSON.stringify(obj);
  if(_s.indexOf(searchValue)>-1){
     if(Array.isArray(obj)){
       return obj.some(function(o){
         if(searchInObject(o, searchValue)) return true;
       });
     }
    else if(typeof(obj) === 'object'){
      for(var k in obj){
        if(searchInObject(obj[k], searchValue)) return true;
      }
    }
    else{
      if(obj === searchValue) return true;
    }
  }
}
console.log(index)

【讨论】:

    【解决方案2】:

    这是我对基于Array.prototype.reduce() 的递归查找索引的看法,它可以处理多级嵌套:

    const recursiveFindIndex = (data, id) =>
      data.reduce((indexes, item, index) => {
        let subIndex;
    
        Array.isArray(item) && (subIndex = recursiveFindIndex(item, id));
    
        if (subIndex && subIndex.length) {
          return indexes.concat([index], subIndex);
        }
    
        item.id === id && (indexes.push(index));
    
        return indexes;
      }, []);
    
    const data = [
      { id: 0 },
      [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
      [{ id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }, [
        { id: 10 }, { id: 11 }, { id: 12 }, { id: 13 }, { id: 14 }]
      ]
    ];
    
    console.log('id: 3', recursiveFindIndex(data, 0));
    console.log('id: 3', recursiveFindIndex(data, 3));
    console.log('id: 6', recursiveFindIndex(data, 8));
    console.log('id: 12', recursiveFindIndex(data, 12));
    console.log('id: 3', recursiveFindIndex(data, 20));

    还有一个使用 for 循环的更通用的性能(它将停止搜索并在找到匹配项后立即返回)版本:

    const recursiveFindIndex = (arr, predicate) => {
      let subIndex;
      
      for(let i = 0; i < arr.length; i++) {
        if(Array.isArray(arr[i])) {
          subIndex = recursiveFindIndex(arr[i], predicate);
          
          if(subIndex !== -1) {
            return [i].concat(subIndex);
          }
        } else if(predicate(arr[i])) {
          return [i];
        }
      }
    
      return -1;
    };
    
    const data = [
      { id: 0 },
      [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }, { id: 5 }],
      [{ id: 6 }, { id: 7 }, { id: 8 }, { id: 9 }, [
        { id: 10 }, { id: 11 }, { id: 12 }, { id: 13 }, { id: 14 }]
      ]
    ];
    
    console.log('id: 0', recursiveFindIndex(data, (item) => item.id === 0));
    console.log('id: 3', recursiveFindIndex(data, (item) => item.id === 3));
    console.log('id: 6', recursiveFindIndex(data, (item) => item.id === 8));
    console.log('id: 12', recursiveFindIndex(data, (item) => item.id === 12));
    console.log('id: 20', recursiveFindIndex(data, (item) => item.id === 20));

    【讨论】:

      【解决方案3】:

      那么,是这样的吗?

      这可能不是最优雅的解决方案,但它确实有效:

      const newData = { id: 1 };
      const data = [[{id: 0}, {id: 1}], [{id: 2}, {id: 3}]];
      
      data.reduce((res, x, i) => {
        let j = x.findIndex(y => y.id === newData.id);
      
        if (~j) {
          return [i, j];
        }
      
        return res;
      }, [-1, -1]);
      

      【讨论】:

        【解决方案4】:

        另一个使用reduce:

        const data = [
            [{ id : 1}, { id: 4 }],
          [{ id :2 }, { id : 3}]
        ]
        
        const findIJ = ( data, id ) => 
          data.reduce( (p, c, i) => {
            let j = c.findIndex( x => x.id === id );
            if( j > - 1){
                p = { i, j }
            }
            return p;
          }, { i : -1, j : -1 });
        

        https://jsfiddle.net/05cubh2b/

        【讨论】:

          猜你喜欢
          • 2019-07-24
          • 2019-07-05
          • 1970-01-01
          • 2021-03-03
          • 1970-01-01
          • 1970-01-01
          • 2015-10-11
          • 1970-01-01
          • 2021-02-03
          相关资源
          最近更新 更多