簡體   English   中英

使用 lodash 深度展平集合中的所有項目

[英]deep flatten all items in collection using lodash

我正在尋找一個看起來像這樣的數組:

[{
    "id": 0,
    "text": "item 0"
}, {
    "id": 1,
    "items": [{
        "id": 2,
        "text": "item 2"
    }, {
        "id": 3,
        "items": [{
            "id": 4,
            "text": "item 4"
        }]
    }]
}]

進入這個

[{
    "id": 0,
    "text": "item 0"
}, {
    "id": 2,
    "text": "item 2"
}, {
    "id": 4,
    "text": "item 4"
}]

基本上保留所有沒有“項目”屬性的元素,如果有,則遞歸遍歷所有“項目”arrays 深度。

我確實可以寫一個遞歸的 function,但我正在尋找一種漂亮的 lodash 或下划線方法來解決這個問題。

在 lodash 或下划線中沒有針對此的簡潔功能。 我認為遞歸函數是你最好的選擇:

function collect(array, result) {
  array.forEach(function(el) {
    if(el.items) {
      collect(el.items, result);
    } else {
      result.push(el);
    }
  });
}

 var array = [{ "id": 0, "text": "item 0" }, { "id": 1, "items": [{ "id": 2, "text": "item 2" }, { "id": 3, "items": [{ "id": 4, "text": "item 4" }] }] }]; function collect(array, result) { array.forEach(function(el) { if(el.items) { collect(el.items, result); } else { result.push(el); } }); } var result = []; collect(array, result); console.log(result);

也可以使用原生的flatMap function:

const tree = [{
    "id": 0,
    "text": "item 0"
}, {
    "id": 1,
    "items": [{
        "id": 2,
        "text": "item 2"
    }, {
        "id": 3,
        "items": [{
            "id": 4,
            "text": "item 4"
        }]
    }]
}]

function flattenTree(tree){
   return tree.flatMap( item => item.items ? [item, ...flattenTree(item.items)] : item);
}


flattenTree(tree);

如果你想刪除道具“項目”,你可以這樣做:

const tree = [{
    "id": 0,
    "text": "item 0"
}, {
    "id": 1,
    "items": [{
        "id": 2,
        "text": "item 2"
    }, {
        "id": 3,
        "items": [{
            "id": 4,
            "text": "item 4"
        }]
    }]
}]


function flattenTreeNoItems(tree){
   return tree.flatMap( item => {
    if(item.items){
      const items = item.items;
      delete item.items;
      return [item, ...flattenTreeNoItems(items)];
        }
    return item;
   });
}

flattenTreeNoItems(tree);

今天遇到這個問題,很驚訝 lodash flatMapDeep不起作用。 這是我寫的一個簡單的遞歸 function,它可以滿足您的預期,同時還允許您使用 map。

function flattenTree(items, callback, nestingKey = 'items') {
    let output = []

    items.forEach(item => {
        output.push(callback ? callback(item) : item)
        output = output.concat(flattenTree(item[nestingKey] || [], callback, nestingKey))
    })

    return output
}
  • 第一個參數是你的樹結構
  • 第二個參數是一個可選的回調 function 來控制你想要如何映射結果
  • 如果您在樹中的嵌套鍵不是items ,則可以使用第三個參數

您的用例的示例用法:

let output = flattenTree(items, item => ({
    id: item.id,
    text: item.text
}))

僅提取ID字段的示例:

let ids = flattenTree(items, item => item.id)

lodash/flattenDeep將遞歸地展平一個數組。 例如:

 import {flattenDeep} from 'lodash' const nestedArray = [1, ['2', [3, [{x: 4}]]]] const mixedNestedArray = [1, ['2', [3, [{x: [[4]]}]]]] console.log(flattenDeep(nestedArray)) // [1, '2', 3, {x: 4}] console.log(flattenDeep(mixedNestedArray)) // [1, '2', 3, {x: [[4]]}]

請注意,對象內的嵌套數組不會受到影響,這正是您所期望的。

2 行代碼中可能的解決方案,使用lodash/flatMap

const iteratee = item => (item.items ? flatMap(item.items, iteratee) : item);
const flattenedItems = _.flatMap(sourceItems, iteratee);

寫在我的頭頂上,所以用一粒鹽把它帶走。

暫無
暫無

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

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