简体   繁体   中英

Map an array and return a new one based on the object keys

This is the original array:

let list = [
    {
        city: "new york", 
        current_time: "123", 
        time1: "456", 
        time2: "789",
    },
    {
        city: "london",
        current_time: "123",
        time1: "456",
        time2: "789",
    },
    {
        city: "tokyo",
        current_time: "123",
        time1: "456",
        time2: "789",
    }
]

I'm trying to create an array of arrays where each inner array containing the objects with the city and time. But organized by current_time , time1 or time2 .

The expected result:

result = [
    [{
        city: "new york",
        time: "123"
    }, {
        city: "london",
        time: "123"
    }, {
        city: "tokyo",
        time: "123"
    }],
    [{
        city: "new york",
        time: "456"
    }, {
        city: "london",
        time: "456"
    }, {
        city: "tokyo",
        time: "456"
    }], [{
        city: "new york",
        time: "789"
    }, {
        city: "london",
        time: "789"
    }, {
        city: "tokyo",
        time: "789"
    }]
]

I tried to use map function, but I'm able to create the array just with the current_time, I probably need to iterate the keys but I'm confused if I need to use an forEach or a better way to iterate.

result = list.map((element, index) => {
    if(element.current_time) {
        return { city: element.city, time: element.current_time };
});

You could use an array for the keys and map the the result of mapped values of the given array.

 var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456", time2: "789" }], keys = ["current_time", "time1", "time2"], result = keys.map(k => list.map(o => ({ city: o.city, time: o[k] }))); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

An other approach could be to iterate the data and reduce it by iterating the keys for the assingning of objects with an index of the keys.

 var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456", time2: "789" }], keys = ["current_time", "time1", "time2"], result = list.reduce((r, o) => { keys.forEach((k, i) => (r[i] = r[i] || []).push({ city: o.city, time: o[k] })); return r; }, []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

A slightly changed version for data with some missing keys.

 var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456" }], keys = ["current_time", "time1", "time2"], result = list.reduce((r, o) => { keys.forEach((k, i) => k in o && (r[i] = r[i] || []).push({ city: o.city, time: o[k] })); return r; }, []); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

I hope this helps you

 let list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "1223", time1: "456", time2: "789" }, { city: "tokyo", current_time: "1223", time1: "456", time2: "789" }], obj = {}; list.forEach(function(itm) { if (!obj.hasOwnProperty(itm.current_time)) { obj[itm.current_time] = []; } obj[itm.current_time].push(itm); }); let result = []; var keys = Object.keys(obj); for (var i = 0; i < keys.length; i++) { result.push(obj[keys[i]]); } console.log(result); 

The function map creates a new array with the same length as the original, so, what you need to do is looping that array and group those values.

An alternative is using the function reduce

 let list = [{ city: "new york", current_time: "123", time1: "456", time2: "789"}, { city: "london", current_time: "123", time1: "456", time2: "789"},{ city: "tokyo", current_time: "123", time1: "456", time2: "789"}], keys = ['current_time', 'time1', 'time2'], result = Object.values(list.reduce((a, c) => { keys.forEach(k => (a[c[k]] || (a[c[k]] = [])).push({ city: c.city, time: c[k] })); return a; }, {})); console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

 var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789", }, { city: "london", current_time: "123", time1: "456", time2: "789", }, { city: "tokyo", current_time: "123", time1: "456", time2: "789", } ]; let timeKeys = Object.keys(list[0]); timeKeys.shift(); let finalArray = timeKeys.map(val => list.map(nestedVal => ({ city: nestedVal.city, time: nestedVal[val] }))); console.log(finalArray); 

I took the approach to defined a new empty array and resetting to empty for each element. this array is been populated by running through the loop of each element property which is not the city and pushing a new object with property city and time.

Hope it would be helpful.

 var list = [ { city: "new york", current_time: "123", time1: "456", time2: "789", }, { city: "london", current_time: "123", time1: "456", time2: "789", }, { city: "tokyo", current_time: "123", time1: "456", time2: "789", }]; var arr = [] var result = list.map((ele) => { arr = [] for(var prop in ele){ if(prop != 'city') arr.push({city: ele['city'], time: ele[prop]}) } return arr }) console.log('result =', result) 

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