Javascript函数 - 从一种数据结构转换到另一种数据结构

时间:2017-09-14 23:08:58

标签: javascript angular reactjs data-structures

我正在尝试构建一个JS函数来转换数据结构的形式  '开始'到'预期'的形式。

使用JS map()方法,我将如何为以下关联数组执行此操作 -

const start = {
  Clients: {
    171: { id: 171, name: 'John Smith', active: false },
    172: { id: 172, name: 'Jacob Jacobson', active: true },
    1441: { id: 1441, name: 'Eric Ericsson', active: true },
  },
  Caregivers: {
    1: { id: 1, name: 'John Johnson', active: true },
    37: { id: 37, name: 'James Jameson', active: false },
    15: { id: 15, name: 'Aaron Aaronson', active: true },
  },
  Doctors: {
    1147: { id: 1147, name: 'Doc Docson', active: true },
  },
  Hospitals: {
    115: { id: 115, active: false, name: "St. Mary's" },
  },
  Applicants: {
    17345: { id: 17345, name: 'Bob Bobson', active: true },
    17346: { id: 17346, name: 'Jeff Jeffson', active: false },
    17347: { id: 17347, name: 'Frank Frankson', active: true },
    17348: { id: 17348, name: 'Bill Billson', active: true },
  },
};

需要转换为 -

const expected = [
  { label: 'Bill Billson', value: 17348, group: 'Applicants' },
  { label: 'Bob Bobson', value: 17345, group: 'Applicants' },
  { label: 'Frank Frankson', value: 17347, group: 'Applicants' },
  { label: 'Aaron Aaronson', value: 15, group: 'Caregivers' },
  { label: 'John Johnson', value: 1, group: 'Caregivers' },
  { label: 'Eric Ericsson', value: 1441, group: 'Clients' },
  { label: 'Jacob Jacobson', value: 172, group: 'Clients' },
  { label: 'Doc Docson', value: 1147, group: 'Doctors' },
];

3 个答案:

答案 0 :(得分:1)

.map()无法直接在对象上使用;相反,您需要使用Object.keys



const start = {
    Clients: {
        171: { id: 171, name: 'John Smith', active: false },
        172: { id: 172, name: 'Jacob Jacobson', active: true },
        1441: { id: 1441, name: 'Eric Ericsson', active: true }
    },
    Caregivers: {
        1: { id: 1, name: 'John Johnson', active: true },
        37: { id: 37, name: 'James Jameson', active: false },
        15: { id: 15, name: 'Aaron Aaronson', active: true }
    },
    Doctors: {
        1147: { id: 1147, name: 'Doc Docson', active: true }
    },
    Hospitals: {
        115: { id: 115, active: false, name: "St. Mary's" }
    },
    Applicants: {
        17345: { id: 17345, name: 'Bob Bobson', active: true },
        17346: { id: 17346, name: 'Jeff Jeffson', active: false },
        17347: { id: 17347, name: 'Frank Frankson', active: true },
        17348: { id: 17348, name: 'Bill Billson', active: true }
    }
};

// Get an array of properties in 'start'
//   then use Array.reduce() to loop over each item 
const expected = Object.keys(start).reduce( (res, gKey) => {

    // gKey = 'group' name
    // gVal = 'group' value
    let gVal = start[gKey];
    
    // loop over each item in the 'group'
    Object.keys(gVal).forEach(iKey => {
    
        // iKey = 'group.item' name
        // iVal = 'group.item' value
        let iVal = gVal[iKey];
        
        // if the value's .active property is truthy
        if (iVal.active) {
        
            // format the result as desired and add it to the result array
            res.push({
                label: iVal.name,
                value: iKey,
                group: gKey
            });
        }
    });
    
    // return the result array
    return res;
    
// start the .reduce() with an empty array
}, []);
console.log(expected);




答案 1 :(得分:0)

要循环对象,您可以使用for ... in循环,也可以使用Object.keys来获取键数组。对于... in将包含继承的属性,因此您可能需要手动过滤它们。 Object.keys只返回自己的属性,因此不需要进行过滤(但如果需要继承属性,它也不合适)

for ... in的示例:

for (var prop in start) {
    if (start.hasOwnProperty(prop)) {
        // logs out 'Clients', then 'Caregivers', then 'Doctors', then 'Hospitals', then 'Applicants'
        console.log(prop);
    }
}

Object.keys示例:

//produces array ['Clients', 'Caregivers', 'Doctors', 'Hospitals', 'Applicants']
var keys = Object.keys(start); 

因此,如果你想使用.map,你可以从这开始,并填写它以做任何你想做的事情:

Object.keys(start)
    .map(key => {
        //do something with start[key]
        //perhaps you could get Object.keys(start[key]) and loop over that as well.
    });

答案 2 :(得分:0)

没有'forEach'的解决方案:

function transform(data) {
    Object.entries(data).map(item => Object.values(item[1])
    .map(i => i.group = item[0]))
    .reduce(( acc, cur ) => acc.concat(cur), [])
    .filter(item => item.active === true)
    .sort((a, b) => a.group - b.group)
    .map(item => {
      let expected = {};
      expected.label = item.name;
      expected.value = item.id;
      expected.group = item.group;
    });
   
    return expected;
}