将对象数组转换为转置的对象数组

时间:2018-06-19 05:38:28

标签: javascript highcharts javascript-objects

我需要将一个对象数组转换为另一个对象数组,但需要进行转置。这是highcharts接受数组的形式。

我需要从

开始
    var n0 = [{
        "a": 1,
        "b": 4
    }, {
        "a": 2,
        "b": 6
    }, {
        "a": 3,
        "b": 8
    }]

    var n1 = [{
        "name": "a",
        "data": [1, 2, 3]
    }, {
        "name": "b",
        "data": [4, 6, 8]
    }];

如何改变

            var input = [{
                "date": "JAN",
                "category": "abc",
                "thevalue": 5
            }, {
                "date": "JAN",
                "category": "xyz",
                "thevalue": 4
            }, {
                "date": "FEB",
                "category": "abc",
                "thevalue": 9
            }, {
                "date": "FEB",
                "category": "xyz",
                "thevalue": 10
            }]

                var output = [{
                    "name": "abc",
                    "data": [5,9]
                }, {
                    "name": "xyz",
                    "data": [4, 10]
                }];

这可以用相同的功能完成吗?我已经阅读了两本javascript书籍但不知何故这些谜题远远超过我的能力。我甚至不知道从哪里开始学习。我想我可以重读关于对象和数组的章节,问题是那些例子非常基础。

3 个答案:

答案 0 :(得分:1)

reduce将项目放入name索引的对象中,然后获取该对象的值:



var n0 = [{
  "a": 1,
  "b": 4
}, {
  "a": 2,
  "b": 6
}, {
  "a": 3,
  "b": 8
}];
console.log(
  Object.values(
    n0.reduce((a, obj) => {
      Object.entries(obj).forEach(([name, val]) => {
        if (!a[name]) a[name] = { name, data: [] };
        a[name].data.push(val);
      })
      return a;
    }, {})
  )
);




答案 1 :(得分:1)

解决此问题的一种简单方法是记住,您使用的每个键都存在于输入数组的每个条目中。使用Object.keys获取任何这些对象的所有键的数组,可以得到names的列表。从那里,遍历该数组并继续使用.map选择您感兴趣的特定键值。

只是抬头,如果您的数组为空,这将抛出错误。如果您遇到拐角情况,您可以提前退货。

如果您对我使用的语法有任何疑问,请随时要求澄清。

    var n0 = [{
      "a": 1,
      "b": 4,
      "c": 5
    }, {
      "a": 2,
      "b": 6,
      "c": 4
    }, {
      "a": 3,
      "b": 8,
      "c": 10
    }]

    function transposeObject(array) {
      const newArr = [] // an empty array I make to store my values that I will eventually return
      const arrayOfKeys = Object.keys(array[0]) // selecting the first element in the array. Taking the keys as an array
      arrayKeys.forEach(name => {
        const newObj = { name }; // new object. I insert the name to start.
        const arrayOfNumbersByKeyName = array.map(object => object[name]) // create new array that is only compromised of the value from object[name], where name is a variable representing a key from arrayKeys
        newObj.data = arrayOfNumbersByKeyName // insert my newly created array into newObject under the key 'data'
        newArr.push(newObj) // push my fully constructed array into my newArr that I initialized at the top of the function
      });
      return newArr
    }

    console.log(transposeObject(n0))

更新

看起来您正在尝试获取与category中的密钥相关的每个值。道歉,但除非你想编写一个令人难以置信的长算法,否则没有“简单”的方法可以解决这个问题。

一种方法是获取密钥的每个可能值,然后每次filter仅针对特定类别名称。

var input = [{
    "date": "JAN",
    "category": "abc",
    "thevalue": 5
}, {
    "date": "JAN",
    "category": "xyz",
    "thevalue": 4
}, {
    "date": "FEB",
    "category": "abc",
    "thevalue": 9
}, {
    "date": "FEB",
    "category": "xyz",
    "thevalue": 10
}]

function generateGraphData(array) {
    const newArr = []
    const arrayOfCategories = array.map(object => object.category)
    const setOfCategories = new Set(arrayOfCategories)
    for (const category of setOfCategories) {
        const filteredCategories = array.filter(obj => obj.category === category)
        const graphData = filteredCategories.map(obj => obj.thevalue)
        newArr.push({ name: category, data: graphData})
    }
    return newArr
}

const data = generateGraphData(input)
console.log(data)

答案 2 :(得分:0)

您可以检查是否提供了移交的名称和值键,然后同时使用这两个键来生成分组结果,否则请使用对象的所有键进行分组。

function groupBy(array, name, value) {
    const
        groupByNameValue = (r, o) => {
            var object = r.find(p => p.name === o[name]);
            if (!object) {
                r.push(object = { name: o[name], data: [] });
            }
            object.data.push(o[value]);
            return r;
        },
        groupByAllKeys = (r, o) => {
            Object.entries(o).forEach(([name, value]) => {
                var object = r.find(p => p.name === name);
                if (!object) {
                    r.push(object = { name, data: [] });
                }
                object.data.push(value);
            });
            return r;
        }

    return array.reduce(name && value ? groupByNameValue : groupByAllKeys, []);
}

var data1 = [{ a: 1, b: 4 }, { a: 2, b: 6 }, { a: 3, b: 8 }],
    data2 = [{ date: "JAN", category: "abc", thevalue: 5 }, { date: "JAN", category: "xyz", thevalue: 4 }, { date: "FEB", category: "abc", thevalue: 9 }, { date: "FEB", category: "xyz", thevalue: 10 }];

console.log(groupBy(data1));
console.log(groupBy(data2, 'category', 'thevalue'));
.as-console-wrapper { max-height: 100% !important; top: 0; }