2016-03-26 2 views
-1

я следующий код, основанный на docsJavascript фильтр в массиве

var arr = [ 
    { id: 15 }, 
    { x: [{ id: 777 }, { id: 'xx' }, { notidproperty: 987 }]}, 
    { id: 1111 } 
]; 

function filterByID(obj) { 
    if ('id' in obj && typeof(obj.id) === 'number' && !isNaN(obj.id)) { 
    return true; 
    } else if (Object.prototype.toString.call(obj) === '[object Array]') { //obj type is Object, not Array 
    obj.filter(filterByID); 
    } else { 
    return false; 
    } 
} 

var arrByID = arr.filter(filterByID); 
console.log('expected length = 3, actual length = ' + arrByID.length); 
console.log(arrByID); 

Как я могу фильтровать «обр» массив? Есть ли другие методы для получения правильного результата?

EDIT: ожидаемый результат фильтруется массив объектов, которые имеют свойство Id с числовым значением

Таким образом, ожидаемые значения Id являются 15, 777, 1111

+0

пожалуйста, добавьте желаемый результат. –

+1

Отсутствует описание того, что вы даже хотите, чтобы этот код выполнял ... см. [Ask]. Обратите внимание также, что ничего не возвращается в состоянии 'else if' – charlietfl

+0

Возможно, вы можете заменить' Object.prototype.toString.call (obj) === '[object Array]') 'с' Array.isArray() ' – Andy

ответ

0

Вы должны изменить следующую ветвь:

if (Object.prototype.toString.call(obj) === '[object Array]') { //obj type is Object, not Array 
    obj.filter(filterByID); 
} 

This только фильтры, но не возвращает никакого результата. И ваш объект с свойством x типа Array здесь не обрабатывается. Итак:

if(obj.x && Array.isArray(obj.x)){ 
    return obj.x.filter(filterByID).length>0 
} 

Или:

if(obj.x && Array.isArray(obj.x)){ 
    obj.x = obj.x.filter(filterByID) 
    return true 
} 

(в зависимости от того, что вы хотите сделать)

+0

Второй вариант - именно то, чего я ожидал! – photostok

0

Почти там. В else if вы ничего не возвращаете. Вместо

obj.filter(filterByID);

попробовать return (obj.filter(filterByID).length > 0);

, потому что, если в результате рекурсивного filterByID массив длиной более 0, вы хотите добавить, что к внешнему результату.

1

Я предлагаю использовать Array#reduce() вместо Array#filter(), потому что вам нужен плоский массив для результата, считать.

Я использую isFinite как чек на id.

function rr(r, a) { 
 
    Object.keys(a).forEach(function (k) { 
 
     if (Array.isArray(a[k])) { 
 
      r = r.concat(a[k].reduce(rr, [])); 
 
     } else { 
 
      isFinite(a.id) && r.push(a); 
 
     } 
 
    }); 
 
    return r; 
 
} 
 

 
var arr = [{ id: 15 }, { x: [{ id: 777 }, { id: 'xx' }, { notidproperty: 987 }] }, { id: 1111 }], 
 
    result = arr.reduce(rr, []); 
 

 
document.write('<pre>' + JSON.stringify(result, 0, 4) + '</pre>');

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