基于对象数组过滤对象数组会返回相同的结果

时间:2017-06-02 13:33:37

标签: javascript arrays ecmascript-6 filtering

目标是将我的React组件中的硬编码数据库列名称删除到配置文件中。而不是使用data.X,它将是data.A,如下所示。这样,如果他们将X改为其他东西,我只需要更改X的配置文件,然后在我的React组件中的任何地方都会更新,因为data.A在组件中。

问题是过滤只返回数据中的最后一个对象。任何帮助将不胜感激,任何有关删除嵌套​​for循环的建议将有助于学习。

期望的输出:

[
    {
        "A": 1,
        "B": 2,
    },
    {
        "A": 4,
        "B": 5,
    },
    {
        "A": 7,
        "B": 8,
    },
];

当前输出:

[
    {
        "A": 7,
        "B": 8,
    },
    {
        "A": 7,
        "B": 8,
    },
    {
        "A": 7,
        "B": 8,
    },
];

fiddle

let data = [
    {
        "X": 1,
        "Y": 2,
        "Z": 3,
    },
    {
        "X": 4,
        "Y": 5,
        "Z": 6,
    },
    {
        "X": 7,
        "Y": 8,
        "Z": 9,
    },
];

let keys = {
    A: 'X',
    B: 'Y',
};
let keyChain = {};
let cleanedData = [];

for (let key in keys) {
    keyChain[key] = '';
}

for (let i in data) {
    cleanedData[i] = keyChain;
    for (let key in keys) {
        if (keys[key] in data[i]) {
            cleanedData[i][key] = data[i][keys[key]];
        };
    }
}
console.log(cleanedData);

5 个答案:

答案 0 :(得分:1)

只需将您的最后一部分代码更改为以下内容即可实现

for (let i in data) {
    cleanedData[i] ={}
    for (let key in keys) {
        if (keys[key] in data[i]) {
            cleanedData[i][key] = data[i][keys[key]];
        };
    }
}
console.log(cleanedData);



let data = [
    {
        "X": 1,
        "Y": 2,
        "Z": 3,
    },
    {
        "X": 4,
        "Y": 5,
        "Z": 6,
    },
    {
        "X": 7,
        "Y": 8,
        "Z": 9,
    },
];

let keys = {
    A: 'X',
    B: 'Y',
};
let keyChain = {};
let cleanedData = [];

// construct the placeholder key value pair array
for (let key in keys) {
    keyChain[key] = '';
}

// check keys to see if there's a match with the json
for (let i in data) {
    cleanedData[i] ={}
    for (let key in keys) {
        if (keys[key] in data[i]) {
            cleanedData[i][key] = data[i][keys[key]];
        };
    }
}
console.log(cleanedData);




希望有所帮助

答案 1 :(得分:1)

那是因为您重复使用与新占位符相同的keyChain对象,因此这是同一个对象。您需要每次都创建一个新的:

cleanedData[i] = { ...keyChain }; // instead of cleanedData[i] = keyChain;

Fiddle

答案 2 :(得分:1)

恕我直言,你错过的是keyChain对象对每个cleaningData数组元素使用相同。您必须始终记住JavaScript使用对象的引用,因此每行:

cleanedData[i] = keyChain; // same object
// ...
cleanedData[i][key] = data[i][keys[key]];
// modify keyChain object attributes

在结果中,您有一个对同一对象的引用数组,该值是最后一次修改。

尝试使用(ES5方式):

 cleanedData[i] = new Object(); // new object

答案 3 :(得分:1)

解决问题的方式比预期的要容易。只需使用map

let filteredData = data.map((item) => ({'A' : item.X, 'B' : item.Y}));

您只需将每个项目的element.X映射到A,将element.Y映射到B每次都映射到新对象。

let data = [
    {
        "X": 1,
        "Y": 2,
        "Z": 3,
    },
    {
        "X": 4,
        "Y": 5,
        "Z": 6,
    },
    {
        "X": 7,
        "Y": 8,
        "Z": 9,
    },
];

let filteredData = data.map((item) => ({'A' : item.X, 'B' : item.Y}));
console.log(filteredData);

上面的脚本需要1496412529493.929ms来完成,而接受的答案中的那个需要1496412584210.4958ms,这有点慢。

答案 4 :(得分:0)

const data = [
    {
        "X": 1,
        "Y": 2,
        "Z": 3,
    },
    {
        "X": 4,
        "Y": 5,
        "Z": 6,
    },
    {
        "X": 7,
        "Y": 8,
        "Z": 9,
    },
];

const keys = {
    A: 'X',
    B: 'Y',
};

let keysReMap = {};
for (var [key, value] of Object.entries(obj)) {
    keysReMap[value] = key;
}

const cleanedData = data.map((val, key) => {
    const newKey = keysReMap[key];
    return {
        [newKey]: val
    };
});