2016-11-02 27 views
2

我有兩個數組,每個元素都是一個對象:如何根據引用的值從另一個對象擴展對象?

var cars = [{ 
    brand: "VW", 
    brand_id: "1", 
    models: [ 
    { 
     name: "Golf", 
     model_id: "1" 
    }, 
    { 
     name: "Passat", 
     model_id: "2" 
    } 
    ] 
}, 
{ 
    brand: "BMW", 
    brand_id: "2", 
    models: [ 
    { 
     name: "X3", 
     model_id: "1" 
    }, 
    { 
     name: "X5", 
     model_id: "2" 
    } 
    ] 
}]; 

var drivers = [{ 
    name: "Test Driver", 
    cars: [ 
    { 
     brand_id: "1", 
     model_id: "1" 
    }, 
    { 
     brand_id: "2", 
     model_id: "1" 
    } 
    ] 
}] 

什麼是模型的名稱複製到汽車對象爲每個驅動程序的最佳方式?這是預期的結果:

var drivers = [{ 
    name: "Test", 
    cars: [ 
    { 
     brand_id: "1", 
     model_id: "1", 
     name: "Golf" 
    }, 
    { 
     brand_id: "2", 
     model_id: "1", 
     name: "X3" 
    } 
    ] 
}] 

我的想法是通過驅動程序,然後通過汽車循環爲每個驅動程序,然後在每個汽車循環,然後循環......如此多的環路的。我希望這是一個更簡單的方法來解決這個問題。

回答

0

由於數據結構,您無法避免循環。但是你可以做一個相當乾淨的方式

var cars = [{"brand":"VW","brand_id":"1","models":[{"name":"Golf","model_id":"1"},{"name":"Passat","model_id":"2"}]},{"brand":"BMW","brand_id":"2","models":[{"name":"X3","model_id":"1"},{"name":"X5","model_id":"2"}]}]; 
 
var drivers = [{"name":"Test Driver","cars":[{"brand_id":"1","model_id":"1"},{"brand_id":"2","model_id":"1"}]}]; 
 

 
drivers.forEach(expandCars); 
 

 
function expandCars(driver) { 
 
    // map each car to list of car brands filtered by brand ID 
 
    // then to resulting list of car models by model ID 
 
    driver.cars = driver.cars.map(car => { 
 
    var carModels = cars.filter(carBrand => carBrand.brand_id == car.brand_id)[0].models; 
 
    var model = carModels.filter(carModel => carModel.model_id == car.model_id)[0]; 
 
    
 
    return Object.assign(car, model); 
 
    }); 
 
} 
 

 

 

 
console.log(drivers);

老實說這個數據結構似乎不必要的複雜性。爲什麼cars是品牌列表,每個品牌都有一個型號列表?爲什麼不將cars陣列看起來像driver.cars陣列,只是一個扁平列表,其中每個對象都有品牌和型號?這將使搜索汽車結構更容易。 ModelID也應該在所有品牌中都是唯一的,因此您只需檢查型號ID並知道如果型號相同,品牌必須相同。

+0

謝謝!數據結構實際上完全不同(在內容上),只是試圖簡化它的例子和二手車/品牌/模型。 – passatgt

+0

而不是使用'過濾器'和採取結果的第一個元素,這些天'find'通常是可取的。 –

0

您可以使用兩個forEach()循環執行此操作,以便循環drivers陣列中的每個對象,然後循環當前對象內的cars數組。之後,您可以使用兩個find()循環找到與brand_id相同的汽車陣列中的物體,然後在模型內部找到具有相同對象model_id並返回name

var cars = [{"brand":"VW","brand_id":"1","models":[{"name":"Golf","model_id":"1"},{"name":"Passat","model_id":"2"}]},{"brand":"BMW","brand_id":"2","models":[{"name":"X3","model_id":"1"},{"name":"X5","model_id":"2"}]}]; 
 
var drivers = [{"name":"Test Driver","cars":[{"brand_id":"1","model_id":"1"},{"brand_id":"2","model_id":"1"}]}]; 
 

 
drivers.forEach(function(e) { 
 
    e.cars.forEach(function(c) { 
 
    c.name = cars.find(function(a) { 
 
     return a.brand_id == c.brand_id; 
 
    }).models.find(function(a) { 
 
     return c.model_id == a.model_id; 
 
    }).name 
 
    }) 
 
}) 
 

 
console.log(drivers)

0

你可以使用一個哈希表的汽車和分配後的名稱。

var cars = [{ brand: "VW", brand_id: "1", models: [{ name: "Golf", model_id: "1" }, { name: "Passat", model_id: "2" }] }, { brand: "BMW", brand_id: "2", models: [{ name: "X3", model_id: "1" }, { name: "X5", model_id: "2" }] }], 
 
    drivers = [{ name: "Test Driver", cars: [{ brand_id: "1", model_id: "1" }, { brand_id: "2", model_id: "1" }] }], 
 
    hash = Object.create(null); 
 

 
cars.forEach(function (brands) { 
 
    brands.models.forEach(function (model) { 
 
     hash[[brands.brand_id, model.model_id].join('|')] = model; 
 
    }); 
 
}); 
 

 
drivers.forEach(function (driver) { 
 
    driver.cars.forEach(function (car) { 
 
     car.name = hash[[car.brand_id, car.model_id].join('|')].name; 
 
    }); 
 
}); 
 

 
console.log(drivers);
.as-console-wrapper { max-height: 100% !important; top: 0; }

0

使用Array.prototype.reduce與哈希表一起的另一個解決方案 - 請參閱下面的演示:

var cars=[{brand:"VW",brand_id:"1",models:[{name:"Golf",model_id:"1"},{name:"Passat",model_id:"2"}]},{brand:"BMW",brand_id:"2",models:[{name:"X3",model_id:"1"},{name:"X5",model_id:"2"}]}]; 
 
var drivers=[{name:"Test Driver",cars:[{brand_id:"1",model_id:"1"},{brand_id:"2",model_id:"1"}]}]; 
 

 
var result = drivers.reduce(function(hash) { 
 

 
    // create a hash table first 
 
    cars.forEach(function(element) { 
 
    element.models.forEach(function(model) { 
 
     hash[element.brand_id + "|" + model.model_id] = model.name; 
 
    }); 
 
    }); 
 

 
    // now reduce it to obtain the result 
 
    return function(prev, curr) { 
 
    curr.cars.forEach(function(element) { 
 
     element.name = hash[element.brand_id + "|" + element.model_id]; 
 
    }); 
 
    prev.push(curr); 
 
    return prev; 
 
    }; 
 
}(Object.create(null)), []); 
 

 
console.log(result);
.as-console-wrapper{top:0;max-height:100%!important;}

+0

@passatgt讓我知道您對此的反饋,謝謝! – kukkuz

0
drivers.cars.forEach(        
    car =>            
    car.name =          
     cars.find(          
     car2 =>          
      car2.brand_id === car.brand_id    
    ) 
     .models.find(        
      model => 
      model.model_id === car.model_id 
     ).name 
) 

英文:

將司機對象中的汽車列表中的每輛汽車的名稱設置爲首先用正確的品牌在汽車對象中查找汽車的結果,然後在該汽車中找到model_id匹配的模型並以其名字命名。

相關問題