簡體   English   中英

通過匹配父級或子級中的關鍵字來過濾嵌套數組

[英]Filter nested array by matching keywords in both parent or child

我需要通過匹配關鍵字來過濾嵌套數組。 它必須返回與父級或其子項之一的name屬性匹配的所有對象,並且還要過濾其子項。

例:

[
  {
    "name": "abc",
    "children": [
      { "name": "abcd" },
      { "name": "efg" }
    ]
  },
  {
    "name": "hjk",
    "children": [
      { "name": "lmn" },
      { "name": "opq" }
    ]
  },
  {
    "name": "xyz",
    "children": [
      { "name": "lmn" },
      { "name": "abcdef" }
    ]
  }
]

如果文本輸入為“ ab”,則它必須返回:

[
  {
    "name": "abc",
    "children": [
      { "name": "abcd" }
    ]
  },
  {
    "name": "xyz",
    "children": [
      { "name": "abcdef" }
    ]
  }
]

(它與父項或至少一個子項匹配,並返回,但父項和子項除外)

現在,我只能像這樣過濾父母:

filteredArray = _.filter(array, (parent) => {
    return _.includes(_.toLower(parent.name), _.toLower(filterText));
});

我該如何修改它以便也過濾孩子?

編輯:父級可以有空或沒有子級數組。

恕我直言,您可以使用Array#reduce()方法執行以下操作:

 arr = [{"name":"abc","children":[{"name":"abcd"},{"name":"efg"}]},{"name":"hjk","children":[{"name":"lmn"},{"name":"opq"}]},{"name":"xyz","children":[{"name":"lmn"},{"name":"abcdef"}]}, {"name": "xyz"}] var input = "ab" filteredArr = arr.reduce((accum, ele) => { var obj = {}; ele['children'] && ele['children'].forEach(e => { if (e['name'].includes(ele['name']) || e['name'].includes(input)) { obj['name'] = ele['name']; obj['children'] ? (obj['children'].push(e)) : (obj['children'] = [], obj['children'].push(e)) } }) if (Object.keys(obj).length > 0) accum.push(obj); return accum; }, []) console.log(filteredArr); 

對於每個元素,請檢查名稱並過濾其子元素,如果其中一個為真,則將具有已過濾子元素的元素推入新數組

 const data = [{"name": "abc", "children": [{ "name": "abcd" }, { "name": "efg" } ] }, {"name": "hjk","children": [{ "name": "lmn"}, { "name": "opq" } ]}, { "name": "xyz","children": [{ "name": "lmn" },{"name": "abcdef" } ] }, {"name": "abc"}, {"name": "abc", children: []}]; const res = data.reduce((acc, a) => { const ch = a.children && a.children.filter(b => b.name.includes('ab')); if(ch && ch.length) acc.push({...a, children: ch}); else if(a.name.includes('ab')) acc.push({ name: a.name }); return acc; }, []); console.log(res); 

lodash並沒有真正的需要。 #nodash! 只是現代香草JS:

const regExp = new RegExp(filterText, 'i');

const result = array.reduce((acc, { name, children = [] }) => {
  const next = children.filter(child => child.name.match(regExp));

  if (name.match(regExp) || next.length > 0) {
    acc.push({ name, children: next });
  }

  return acc;
}, []);

如果未找到子字符串,則name.match(regExp)將返回null

children = []處理parent沒有孩子的情況。

另外,請注意,使用RegExp檢查子字符串應該比執行多次轉換和查找(例如toLowerincludes )要快得多。

這是您的示例的工作副本

var arrayList = [
  {
    "name": "abc",
    "children": [
      { "name": "abcd" },
      { "name": "efg" }
    ]
  },
  {
    "name": "ab",
    "children": [
      { "name": "lmn" },
      { "name": "opq" }
    ]
  },
  {
    "name": "jdfj",
    "children": [
      { "name": "lmn" },
      { "name": "abcdef" }
    ]
  }
];

function filterArray(arrayList, search){
    return arrayList.filter((item) => {
        let childrens = item.children;
        if(childrens && childrens.length){
          item.children = filterArray(childrens, search);
          if(item.children && item.children.length){
              return true;
          }
        }
        return item.name.indexOf(search) > -1;
    });
}

const filter = filterArray(arrayList, 'ab');

console.log(filter);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM