【问题标题】:Filter array of objects based on array of objects returns same results根据对象数组过滤对象数组返回相同的结果
【发布时间】:2017-11-03 22:37:48
【问题描述】:

目标是将我的 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);

【问题讨论】:

  • 他的意思可能是硬编码 -)) 或手动输入
  • @Chad 你想要的输出是什么?最后你想看什么?
  • @marmeladze 已更新!
  • 所以3 应该飞走。好

标签: javascript arrays ecmascript-6 filtering


【解决方案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);

希望对你有帮助

【讨论】:

    【解决方案2】:

    这是因为您重用了相同的 keyChain 对象作为新的占位符,所以这是同一个对象。您每次都需要创建一个新的:

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

    Fiddle

    【讨论】:

      【解决方案3】:
      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
          };
      });
      

      【讨论】:

        【解决方案4】:

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

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

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

        尝试使用类似(ES5方式):

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

        【讨论】:

          【解决方案5】:

          这比预期的要容易解决。只需使用map

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

          您每次只是将每个项目的element.X 映射到Aelement.YB 到一个新对象。

          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,这有点慢。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-03-21
            • 1970-01-01
            • 2018-12-25
            • 2020-12-03
            • 1970-01-01
            • 1970-01-01
            • 2020-12-14
            相关资源
            最近更新 更多