简体   繁体   中英

JavaScript build nested array from string values

From my data source I am getting values like;

USA        |Arizona
USA        |Florida
UK         |England |Northamptonshire
UK         |England |Derbyshire
UK         |Wales   |Powys
Switzerland|Lucern

These are flat text values that repeat in a column.

I need to build them dynamically into nested array

source: [
    {title: "USA",  children: [
      {title: "Arizona"},
      {title: "Florida"}
    ]}
  ],

As per https://github.com/mar10/fancytree/wiki/TutorialLoadData

Unfortunately my brain has stopped working today I am can't see a elegant way.

Any pointers would be most gratefully appreciated.

So I solved this eventually using a post from Oskar

 function getNestedChildren(arr, parent) { var out = [] for(var i in arr) { if(arr[i].parent == parent) { var children = getNestedChildren(arr, arr[i].id) if(children.length) { arr[i].children = children } out.push(arr[i]) } } return out } 

http://oskarhane.com/create-a-nested-array-recursively-in-javascript/

This builds the nested array.

To ensure inferred values were present (eg USA which is in the hierarchy but is not a unique value).

  var CountryArray = CountryText.split("|"); // Variables to hold details of each section of the Country path being iterated var CountryId = ''; var CountryParentPrefix = ''; var CountryParent = ''; // Iterate each section of the delimeted Country path and ensure that it is in the array for(var i in CountryArray) { var CountryId = CountryParentPrefix+CountryArray[i]; // Find the Country id in the array / add if necessary var result = FlatSource.filter(function (Country) { return Country.id == CountryId }); if (result.length == 0) { // If the Country is not there then we should add it var arrCountry = {title:CountryArray[i], parent:CountryParent, id:CountryId}; FlatSource.push(arrCountry); } // For the next path of the heirarchy CountryParent = CountryId; CountryParentPrefix = CountryId+'|'; } 

I did not use Sven's suggestion but I suspect that it is equally valid.

Turn it to JSON:

var str = '"USA|Arizona","USA|Florida","UK|LonelyIsland","UK|England|Northamptonshire","UK|England|Derbyshire","UK|Wales|Powys","UK|England|London|Soho","Switzerland|Lucern';

var jsonStr = "[[" + str.replace(/,/g,'],[') + "\"]]";
jsonStr = jsonStr.replace(/\|/g,'","');
var nested = JSON.parse(jsonStr);

Then play with parents and children.

function findObject(array, key, value) {
    for (var i=0; i<array.length; i++) {
        if (array[i][key] === value) {
            return array[i];
        }
    }
    return null;
}

function obj(arr){
    this.title = arr.shift();
}

obj.prototype.addChild = function(arr){
    var tmp = new obj(arr);
    if(typeof this.children === 'undefined'){
        this.children = new Array();
        result = this.children[this.children.push(tmp)-1];
    }else{
        result = findObject(this.children, 'title', tmp.title);
        if(!result)
            result = this.children[this.children.push(tmp)-1];
    }
    return result;
}

obj.prototype.addChildren = function(arr){
    var obje = this;
    while(arr.length>0)
        obje = obje.addChild(arr);
}


var finArr = [];
for(i=0; i<nested.length; i++){
    var recc = new obj(nested[i]);
    if(oldObj = findObject(finArr, 'title', recc.title)){
        oldObj.addChildren(nested[i]);
    }else{
        if(nested[i].length>0)
                recc.addChildren(nested[i]);
        finArr.push(recc);        
    }
}

console.log('------------------------------------------')
console.log(JSON.stringify(finArr));
console.log('--------------------The End---------------')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM