2016-10-26 2 views
2

Если у меня есть массив, содержащий объекты, где каждый объект имеет свойство ID, я могу найти индекс с помощью:Найти индекс в двухмерном массиве

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

Но что, если данные были массив массив объектов ? Есть ли хороший способ получить два индекса для этой структуры данных? Таким образом, data.findIndex вернет i и j в удобной форме.

+0

могло быть несколько объектов в каждом вложенном массиве? – RomanPerekhrest

+0

http://stackoverflow.com/a/16102897/1398867 вместо примитива, проверьте на 'id' на объекте' theArray [i] .id == valueToSearch' – Venugopal

ответ

1

Это мой взгляд на рекурсивный индексе находит на основе 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));

и более общее назначение прочего производительное (это остановит поиск и вернуться, как только будет найдена совпадение) версия с использованием цикла для обработки:

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));

0

Итак, что-то вроде этого?

Это, вероятно, не самое элегантное решение, но оно работает:

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]); 
0

Вы можете использовать Array.includes внутри findIndex если сво массив значений.

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)

0

Еще один использованием 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/

Смежные вопросы