使对象数组中的对象架构统一的最快方法

时间:2018-07-19 09:29:26

标签: javascript algorithm

我有一个坐标(rawData = [x,y1,y2,y3,...] big 数组(长度:10k),如下所示:

rawData = [
    {x: 1, y1: 1, y2: 13, y3: 2},
    {x: 2, y1: 2, y2: 23, y3: 2},
    {x: 3, y1: 3, y2: 33, y3: 2, y4: 4},
    {x: 4, y1: 4, y2: 43, y3: 2, y5: 5},
]

可以看出,由于schema的变化,该数组中的对象不一致。

使该数组保持一致以使其具有相同的schema的最快方法是什么?

如果对象没有任何给定键,则可以使用默认值(例如0)对其进行初始化,以使processedData如下:

processedData = [
    {x: 0, y1: 1, y2: 13, y3: 2, y4: 0, y5: 0},
    {x: 1, y1: 2, y2: 23, y3: 2, y4: 0, y5: 0},
    {x: 2, y1: 3, y2: 33, y3: 2, y4: 4, y5: 0},
    {x: 3, y1: 4, y2: 43, y3: 2, y4: 0, y5: 5},
]

编辑:我希望有一个解决方案,而无需循环整个数组,因为该数组很大,或者为此有一些优化的解决方案。

4 个答案:

答案 0 :(得分:3)

您可以首先通过迭代原始对象并收集键来创建骨架对象。

然后,在Object.assign的帮助下,您可以将覆盖骨架的值与原始对象具有的值结合起来,其余的将保持不变。

请参见下面的演示

var rawData = [
    {x: 1, y1: 1, y2: 13, y3: 2},
    {x: 2, y1: 2, y2: 23, y3: 2},
    {x: 3, y1: 3, y2: 33, y3: 2, y4: 4},
    {x: 4, y1: 4, y2: 43, y3: 2, y5: 5},
];

var def = {};

// Create the skeleton object
rawData.forEach(item => {
  Object.keys(item).forEach(k => {
    def[k] = 0;
  })
})

// Extend the skeleton with original data
var res = rawData.map(item => Object.assign({}, def, item))
console.log(res);

答案 1 :(得分:2)

您可以使用Array.map和模板对象

const rawData = [
    {x: 1, y1: 1, y2: 13, y3: 2},
    {x: 2, y1: 2, y2: 23, y3: 2},
    {x: 3, y1: 3, y2: 33, y3: 2, y4: 4},
    {x: 4, y1: 4, y2: 43, y3: 2, y5: 5},
];

const temp = rawData
.reduce((t, o) => ({...t, ...o}), {});

Object.keys(temp).forEach(k => temp[k] = 0);

const result = rawData.map(o => ({...temp, ...o}));

console.log(result);

答案 2 :(得分:1)

如果发现未知密钥,您可以对数据进行一次循环并更新密钥。

var rawData = [{ x: 1, y1: 1, y2: 13, y3: 2 }, { x: 2, y1: 2, y2: 23, y3: 2 }, { x: 3, y1: 3, y2: 33, y3: 2, y4: 4 }, { x: 4, y1: 4, y2: 43, y3: 2, y5: 5 }],
    keys = [],
    processedData = rawData.reduce((r, o) => {
        var temp = Object.assign({}, o);
        Object.keys(o).forEach(k => {
            if (keys.includes(k)) {
                return;
            }
            r.forEach(p => Object.assign(p, { [k]: 0 }));
            keys.push(k);
        });
        r.push(temp)
        return r;
    }, []);
    
console.log(processedData);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 3 :(得分:0)

起初,您不知道将需要哪些字段。为了找出您需要的字段,您必须查看数组的所有元素。

例如,您建议将数组转换为字符串并据此进行解析的建议可行,但效率极低,因为字符串操作往往很慢,更不用说将数组转换为字符串时,无论如何都要看所有的元素。

由于您绝对需要查看所有元素以找出所有可能的字段,因此需要循环两次数组:首先收集键,然后应用所需的更改:

     TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
                if (ActivityCompat.checkSelfPermission(context,
                        Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
                    return;
                }

                String IMEI_Number = null;
                if (telephonyManager != null) {
                    IMEI_Number = telephonyManager.getDeviceId();
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    String Imei0Id = null;
                    if (telephonyManager != null) {
                        Imei0Id = telephonyManager.getDeviceId(0);
                    }
                    if (null != Imei0Id && !Imei0Id.equals("000000000000000")) {
                        IMEI_Number = Imei0Id;
                    }


}