2017-06-23 8 views
5

मैं एक समस्या पर काम कर रहा हूं जहां मुझे वस्तुओं को एक रूप से दूसरे रूप में समूहित करना है।प्रदर्शन के साथ जावास्क्रिप्ट ऑब्जेक्ट पुनर्गठन

var initialData = [ 
    { 
    house: { id: 1, text: "white" }, 
    room: { id: 1, text: "red" }, 
    price: 2.1 
    }, 
    { 
    house: { id: 1, text: "white" }, 
    room: { id: 2, text: "blue" }, 
    price: 3.1 
    }, 
    { 
    house: { id: 1, text: "white" }, 
    room: { id: 3, text: "red" }, 
    price: 5.8 
    }, 
    { 
    house: { id: 2, text: "black" }, 
    room: { id: 1, text: "yellow" }, 
    price: 9.1 
    }, 
    { 
    house: { id: 2, text: "black" }, 
    room: { id: 2, text: "green" }, 
    price: 7.7 
    }, 
]; 

और नई वस्तु इस तरह दिखना चाहिए:

एक उदाहरण की तुलना में बेहतर 1000 शब्दों है

var finalObject = { 
    houses: [ 
    { 
     id: 1, text: "white", 
     rooms: [ 
     { id: 1, text: "red", price: "2.1" }, 
     { id: 2, text: "blue", price: "3.1" }, 
     { id: 3, text: "red", price: "5.8" } 
     ] 
    }, 
    { 
     id: 2, text: "black", 
     rooms: [ 
     { id: 1, text: "yellow", price: "9.1" }, 
     { id: 2, text: "green", price: "7.7" } 
     ] 
    } 
    ] 
}; 

मैं उनके सभी कमरों के साथ अद्वितीय घरों खोजने के लिए और भी प्रत्येक जोड़ने के लिए कमरे के अंदर प्रारंभिक वस्तु से कीमत।

मैं सोच रहा हूँ के बाद से मैं तत्वों की एक बड़ी राशि होगा यह करने के लिए सबसे अच्छा तरीका है जो?

मेरे पास एकाधिक लूप के साथ कुछ विचार हैं, लेकिन मेरे लिए यह मेरे समाधान को थोड़ा जटिल लगता है।

अपडेट: मेरे सवाल का दोहराव क्योंकि मैं lodash का उपयोग नहीं करते के लिए एक उम्मीदवार के रूप में ही नहीं है, और मेरी वस्तु एक सा है, बस फिर से एकजुट नहीं पुनर्संशोधित किया जाना है।

संभव समाधान (@ से प्रेरित गेल का जवाब)

finalObject = {} 

for (var i = 0; i < initialData.length; ++i) { 
    var item = initialData[i]; 
    var id = item.house.id; 
    if(!finalObject[id]) { 
    finalObject[id] = item.house; 
    finalObject[id].rooms = []; 
    } 
    var room = item.room; 
    room.price = item.price; 

    finalObject[id].rooms.push(room); 
} 

console.log(finalObject); 
+0

ऐसा लगता है कि आप केवल एक पाश की आवश्यकता होगी। आप प्रत्येक तत्व के माध्यम से जा सकते हैं और इसे एक नई सरणी में जोड़ सकते हैं, इसे घर पर आधारित कर सकते हैं, फिर कमरे, फिर आईडी। – victor

+2

आपको उन विचारों को पोस्ट करना चाहिए और समस्या को हल करने के लिए आपने अभी तक क्या लिखा है। – chazsolo

+1

संभावित डुप्लिकेट [कुंजी द्वारा वस्तुओं की सरणी समूह कैसे करें] (https: // stackoverflow।कॉम/प्रश्न/40774697/कैसे-टू-ग्रुप-एरे-ऑफ-ऑब्जेक्ट-बाय-की) –

उत्तर

4

उपयोग Array#reduce:

var myMap = new Map(); 

var keyObj = {}, // ideally your room object with id 


// setting the values 
myMap.set(keyString, "value associated with 'a string'"); // not recommended for your case 

या

var initialData = [{"house":{"id":1,"text":"white"},"room":{"id":1,"text":"red"},"price":2.1},{"house":{"id":1,"text":"white"},"room":{"id":2,"text":"blue"},"price":3.1},{"house":{"id":1,"text":"white"},"room":{"id":3,"text":"red"},"price":5.8},{"house":{"id":2,"text":"black"},"room":{"id":1,"text":"yellow"},"price":9.1},{"house":{"id":2,"text":"black"},"room":{"id":2,"text":"green"},"price":7.7}]; 
 

 
var dict = {}; // helper object 
 
var result = initialData.reduce(function(houses, obj) { // reduce the data 
 
    var house = dict[obj.house.id]; // get the house from the dict by id 
 
    
 
    if(!house) { // if house wasn't found 
 
    house = Object.assign({}, obj.house, { rooms: [] }); // create a new house object 
 
    houses.push(house); // push it into the array of houses 
 
    dict[house.id] = house; // add it to the dict by id 
 
    } 
 
    
 
    house.rooms.push(obj.room); // push the room to the current house 
 
    
 
    return houses; 
 
}, []); 
 

 
console.log(result);

तुम भी उपयोग कर रहा ES6 मानचित्र इसे प्राप्त और वाक्य रचना का प्रसार कर सकते हैं:

const initialData = [{"house":{"id":1,"text":"white"},"room":{"id":1,"text":"red"},"price":2.1},{"house":{"id":1,"text":"white"},"room":{"id":2,"text":"blue"},"price":3.1},{"house":{"id":1,"text":"white"},"room":{"id":3,"text":"red"},"price":5.8},{"house":{"id":2,"text":"black"},"room":{"id":1,"text":"yellow"},"price":9.1},{"house":{"id":2,"text":"black"},"room":{"id":2,"text":"green"},"price":7.7}]; 
 

 
const result = [...initialData.reduce((houses, { house, room }) => { // reduce the data to a Map 
 
    const currentHouse = houses.get(house.id) || Object.assign({}, house, { rooms: [] }); // get the current house from the map by id, or create a new one 
 
    
 
    currentHouse.rooms.push(room); // push the room to the current house 
 
    
 
    return houses.set(currentHouse.id, currentHouse); // set the house to the map, and return it 
 
}, new Map()).values()]; // get the values of the map and spread to an array 
 

 
console.log(result);

2

आप किसी मैप का उपयोग करना चाहिए: एक सहायक वस्तु के साथ

myMap.set(keyObj, 'value associated with keyObj'); // should be rooms 

myMap.size; // the number of items you added 
+0

यह सिर्फ एक अलग डेटा संरचना है, लेकिन जिस तरह से मुझे आवश्यकता है उसमें समूह करने की रणनीति क्या है? –

+1

@ वी। सैमोर घर की कक्षा की चीजों और कमरे की सरणी वाले कमरे की वस्तुएं बनाते हैं, यह मूल्य है। –

+1

आपकी मदद के लिए धन्यवाद, मैं इसे आजमाने के लिए जा रहा हूं, ठीक है! :) –

1

यदि आप प्रारंभिक डेटा सुरक्षित रखना चाहते हैं पर निर्भर करता है या नहीं प्रभावित करेगा उपाय। मैंने माना है कि आप मूल वस्तु को रखना चाहते हैं और एक नया उत्पादन करना चाहते हैं।

यदि आप Map ऑब्जेक्ट का उपयोग करते हैं तो यह याद रखने के लिए आप Map ऑब्जेक्ट का उपयोग कर सकते हैं, जहां मौजूदा घर id संपत्ति हैं। यदि घर को परिणाम में पहले ही डाला जा चुका है, तो आपको बस नया कमरा जोड़ना होगा। अन्यथा, आपको एक नया घर वस्तु बनाने और मानचित्र में इसकी अनुक्रमणिका को स्टोर करने की आवश्यकता है।

function transformHouses(houses) { 
    const houseMap = new Map(); 
    const result = {houses: []}; 

    for(const house of houses) { 
    if(houseMap.has(house.id)) { 
     const index = houseMap.get(house.id); 
     const room = Object.assign({price: house.price}, house.room); 

     result.houses[index].rooms.push(room); 
    } else { 
     const room = Object.assign({price: house.price}, house.room); 
     const entry = Object.assign({rooms: [room]}, house.house) 

     housesMap.set(house.id, result.houses.length); 
     result.houses.push(entry); 
    } 
    } 

    return result; 
} 
1

var houses= {}; 
 

 
initialData.forEach(function(item){ 
 
    
 
    if(!houses[ item.house ]){ 
 
    
 
    houses[ item.house ]= item.house; 
 
    houses[ item.house ].rooms= {}; 
 
    } 
 
    houses[ item.house ].rooms[ item.room.id ]= item.room; 
 
    houses[ item.house ].rooms[ item.room.id ].price= item.price; 
 
    
 
});

संबंधित मुद्दे