Saya memiliki file json kompleks yang harus saya tangani dengan javascript untuk membuatnya hierarkis, untuk kemudian membangun pohon. Setiap entri json memiliki: id: id unik, parentId: id dari simpul induk (yang merupakan 0 jika simpul adalah akar dari pohon) level: tingkat kedalaman dalam pohon
Data json sudah "dipesan". Maksud saya sebuah entri akan memiliki di atas dirinya simpul orangtua atau simpul saudara, dan di bawahnya simpul anak atau simpul saudara.
Memasukkan :
{
"People": [
{
"id": "12",
"parentId": "0",
"text": "Man",
"level": "1",
"children": null
},
{
"id": "6",
"parentId": "12",
"text": "Boy",
"level": "2",
"children": null
},
{
"id": "7",
"parentId": "12",
"text": "Other",
"level": "2",
"children": null
},
{
"id": "9",
"parentId": "0",
"text": "Woman",
"level": "1",
"children": null
},
{
"id": "11",
"parentId": "9",
"text": "Girl",
"level": "2",
"children": null
}
],
"Animals": [
{
"id": "5",
"parentId": "0",
"text": "Dog",
"level": "1",
"children": null
},
{
"id": "8",
"parentId": "5",
"text": "Puppy",
"level": "2",
"children": null
},
{
"id": "10",
"parentId": "13",
"text": "Cat",
"level": "1",
"children": null
},
{
"id": "14",
"parentId": "13",
"text": "Kitten",
"level": "2",
"children": null
},
]
}
Output yang diharapkan:
{
"People": [
{
"id": "12",
"parentId": "0",
"text": "Man",
"level": "1",
"children": [
{
"id": "6",
"parentId": "12",
"text": "Boy",
"level": "2",
"children": null
},
{
"id": "7",
"parentId": "12",
"text": "Other",
"level": "2",
"children": null
}
]
},
{
"id": "9",
"parentId": "0",
"text": "Woman",
"level": "1",
"children":
{
"id": "11",
"parentId": "9",
"text": "Girl",
"level": "2",
"children": null
}
}
],
"Animals": [
{
"id": "5",
"parentId": "0",
"text": "Dog",
"level": "1",
"children":
{
"id": "8",
"parentId": "5",
"text": "Puppy",
"level": "2",
"children": null
}
},
{
"id": "10",
"parentId": "13",
"text": "Cat",
"level": "1",
"children":
{
"id": "14",
"parentId": "13",
"text": "Kitten",
"level": "2",
"children": null
}
}
]
}
javascript
arrays
list
tree
Franck
sumber
sumber
parentId
dari0
sarana tidak ada orang tua id dan harus lapisan atas.Jawaban:
Ada solusi yang efisien jika Anda menggunakan pencarian peta. Jika orang tua selalu mendahului anak-anak mereka, Anda dapat menggabungkan keduanya. Ini mendukung banyak root. Ini memberikan kesalahan pada cabang yang menggantung, tetapi dapat dimodifikasi untuk mengabaikannya. Itu tidak memerlukan perpustakaan pihak ke-3. Sejauh yang saya tahu, ini adalah solusi tercepat.
Jika Anda menyukai teori kompleksitas, solusi ini adalah Θ (n log (n)). Solusi filter rekursif adalah Θ (n ^ 2) yang dapat menjadi masalah untuk set data besar.
sumber
map
mana (secara teori) adalah O (log n).Seperti yang disebutkan oleh @Sander, jawaban @ Halcyon mengasumsikan array yang sudah diurutkan sebelumnya, yang berikut tidak. (Namun ia menganggap Anda telah memuat underscore.js - meskipun itu dapat ditulis dalam javascript vanilla):
Kode
Persyaratan
Ini mengasumsikan properti 'id' dan 'parentid' masing-masing menunjukkan ID dan ID induk. Harus ada elemen dengan ID induk 0, jika tidak, Anda akan mendapatkan kembali array kosong. Elemen yatim dan keturunan mereka 'hilang'
http://jsfiddle.net/LkkwH/1/
sumber
else { parent['children'] = []; }
setelah if-clause pertama untuk memastikan bahwa setiap node memiliki atributchildren
(itu akan kosong jika node tersebut adalah leaf leaf)tree
tidak pernah disahkan sebagai argumen ketika memanggil fungsi secara rekursif, jadi saya pikir garistree = typeof tree !== 'undefined' ? tree : [];
dapat digantikan olehlet tree = [];
null
parent_ids alih-alih 0? Sunting: Nevermind, saya membuatnya berfungsi dengan mengubahid: 0
keid: null
.(BONUS1: NODE MUNGKIN atau MUNGKIN TIDAK DITERBITKAN)
(BONUS2: TIDAK DIPERLUKAN PERPUSTAKAAN PARTAI 3, PLAIN JS)
(BONUS3: Pengguna "Elias Rabl" mengatakan ini adalah solusi tercepat, lihat jawabannya di bawah)
Ini dia:
Berikut ini adalah tes, mungkin membantu Anda untuk memahami bagaimana solusinya bekerja:
sumber
childNodes
hanya saat dibutuhkan? Dengan menghapusnya dari yang pertamaforEach
dan memindahkannya ke dalam yang kedua?Punya masalah yang sama, tapi saya tidak bisa memastikan bahwa data diurutkan atau tidak . Saya tidak bisa menggunakan perpustakaan pihak ke-3 jadi ini hanya vanilla Js; Input data dapat diambil dari contoh @ Stephen;
JS Fiddle
Flat Array to Tree
sumber
mappedArr[mappedElem['parentid']]['children']
gagal karena tidak dapat mengakses kechildren
undefined.Gunakan pendekatan ES6 ini. Bekerja seperti pesona
sumber
daftar fungsi -ke-pohon-lite yang lebih sederhana
npm install list-to-tree-lite
listToTree(list)
sumber:
jsfiddle
sumber
Anda dapat menangani pertanyaan ini hanya dengan dua pengkodean baris:
Tes Online (lihat konsol peramban untuk pohon yang dibuat)
Persyaratan:
1- Instal lodash 4 (perpustakaan Javascript untuk memanipulasi objek dan koleksi dengan metode performant => seperti Linq di c #) Lodash
2- FlatArray seperti di bawah ini:
Terima kasih Pak Bakhshabadi
Semoga berhasil
sumber
Ini mungkin berguna Instal paket -ke-pohon :
atau
Misalnya, miliki daftar:
Gunakan daftar paket-ke-pohon:
Hasil:
sumber
Saya telah menulis skrip pengujian untuk mengevaluasi kinerja dua solusi paling umum (artinya input tidak harus disortir terlebih dahulu dan bahwa kode tidak bergantung pada perpustakaan pihak ketiga), yang diusulkan oleh pengguna shekhardtu ( lihat jawaban ) dan FurkanO ( lihat jawaban ).
http://playcode.io/316025?tabs=console&script.js&output
Solusi FurkanO tampaknya menjadi yang tercepat.
sumber
Ini adalah proposal untuk item yang tidak dipesan. Fungsi ini bekerja dengan satu loop dan dengan tabel hash dan mengumpulkan semua item dengan mereka
id
. Jika simpul root ditemukan, maka objek ditambahkan ke array hasil.sumber
juga melakukannya dengan lodashjs (v4.x)
sumber
Saya suka solusi JavaScript murni @ WilliamLeung, tapi kadang-kadang Anda perlu membuat perubahan pada array yang ada untuk menyimpan referensi ke objek.
Exapmle: https://jsfiddle.net/kqw1qsf0/17/
sumber
sumber
Anda mungkin telah melihat pohon paket util- npm. Ini juga bisa sangat berguna jika Anda ingin memuat data dari tabel data SQL DB. Anda juga dapat dengan mudah menambahkan data tambahan ke node di pohon yang dibuat.
Penafian, saya membuat paket ini.
sumber
Saya punya masalah serupa beberapa hari yang lalu ketika harus menampilkan pohon folder dari array datar. Saya tidak melihat solusi apa pun di TypeScript di sini jadi saya harap ini akan membantu.
Dalam kasus saya orang tua utama hanya satu, juga array rawData tidak harus diurutkan. Solusi didasarkan pada menyiapkan objek temp suka
{parentId: [child1, child2, ...] }
contoh data mentah
def Folder
SOLUSI : Fungsi yang mengembalikan struktur pohon untuk argumen datar
sumber
Berikut adalah fungsi pembantu sederhana yang saya buat dimodelkan setelah jawaban di atas, disesuaikan dengan lingkungan Babel:
sumber
Ini adalah versi modifikasi dari Steven Harris 'yang merupakan ES5 polos dan mengembalikan objek yang dikunci pada id daripada mengembalikan array node di tingkat atas dan untuk anak-anak.
sumber
Ini adalah versi modifikasi dari yang di atas yang berfungsi dengan beberapa item root, saya menggunakan GUID untuk id dan parentIds saya sehingga di UI yang membuat mereka saya meng-hard-item item root code ke sesuatu seperti 0000000-00000-00000-TREE-ROOT-ITEM
var tree = tidak rata (catatan, "TREE-ROOT-ITEM");
sumber
Disalin dari Internet http://jsfiddle.net/stywell/k9x2a3g6/
sumber
Anda dapat menggunakan npm array-to-tree paket https://github.com/alferov/array-to-tree . Itu mengkonversi array polos node (dengan pointer ke node induk) ke struktur data bersarang.
Memecahkan masalah dengan konversi yang diambil dari kumpulan data ke struktur data bersarang (mis. Pohon navigasi).
Pemakaian:
sumber
inilah yang saya gunakan dalam proyek reaksi
pemakaian:
keluaran:
sumber
Anda dapat menggunakan paket "treeify" ini dari Github di sini atau NPM .
Instalasi:
$ npm install --save-dev treeify-js
sumber
Solusi naskah saya, mungkin ini membantu Anda:
Contoh penggunaan:
sumber
Saya menulis versi ES6 berdasarkan jawaban @Halcyon
Prinsip algoritma ini adalah menggunakan "peta" untuk membangun hubungan indeks. Sangat mudah untuk menemukan "item" dalam daftar dengan "parentId", dan menambahkan "anak-anak" ke setiap "item", karena "daftar" adalah hubungan referensi, jadi "root" akan membangun hubungan dengan seluruh pohon.
sumber
Jawab pertanyaan serupa:
https://stackoverflow.com/a/61575152/7388356
MEMPERBARUI
Anda bisa menggunakan
Map
objek yang diperkenalkan di ES6. Pada dasarnya, alih-alih menemukan orang tua dengan mengulangi lagi array, Anda hanya akan mendapatkan item induk dari array oleh id induk seperti Anda mendapatkan item dalam array dengan indeks.Ini adalah contoh sederhana:
sumber
Berdasarkan jawaban @ FurkanO , saya membuat versi lain yang tidak mengubah data asli (seperti yang diminta @ Dac0d3r). Saya benar-benar menyukai jawaban @ shekhardtu , tetapi menyadari bahwa itu harus menyaring data berkali-kali. Saya pikir solusinya bisa menggunakan jawaban FurkanO dengan menyalin data terlebih dahulu. Saya mencoba versi saya di jsperf , dan hasilnya sayangnya (sangat) suram ... Sepertinya jawaban yang diterima benar-benar bagus! Versi saya cukup dapat dikonfigurasi dan gagal, jadi saya tetap membaginya dengan kalian; inilah kontribusi saya:
Dengan parameter opsi, dimungkinkan untuk mengkonfigurasi properti apa yang digunakan sebagai id atau id induk. Dimungkinkan juga untuk mengkonfigurasi nama properti anak-anak, jika seseorang menginginkan
"childNodes": []
atau sesuatu.OP cukup menggunakan opsi default:
Jika id induk adalah falsy (
null
,undefined
atau nilai falsy lainnya) atau objek induk tidak ada, kami menganggap objek tersebut sebagai simpul akar.sumber
Coba ini
Uji di Jsfiddle
sumber
Konversi node Array ke Tree
ES6 berfungsi untuk mengonversi Array node (terkait dengan ID induk ) - ke struktur Tree:
Hasilkan Daftar HTML dari node Tree
Memiliki Pohon kami di tempat, inilah fungsi rekursif untuk membangun Elemen UL> LI:
Waktu demo
Berikut ini adalah contoh yang memiliki array linear dari node dan menggunakan kedua fungsi di atas:
sumber
Ini adalah utas lama tapi saya pikir pembaruan tidak pernah sakit, dengan ES6 Anda dapat melakukannya:
semoga membantu seseorang
sumber