我想按值传递数组,但似乎它是通过引用传递的,数组上的 .map 操作没有给出预期的结果

I want to pass an array by value but it seems like it is passed by reference, .map operations on array not giving expected result

本文关键字:数组 操作 map 结果 引用 按值传递      更新时间:2023-09-26

我在JS中有以下代码:

var result = getData(item, keyName, true); // This function returns a    Key,Value array, of which the value is another array
var arr = [];
for (var count = 0; count < 3; count++) {
    var tmpArray = result.slice(0);
    var newArray = tmpArray.map((res) => {
        var keyEntry = Object.keys(res)[0]; //Gets the key of the entry
        const name = keyName + '_' + count + '.' + keyEntry; //Changes the key so it is prefixed with a certain keyName and count
        res[name] = res[keyEntry]; //use this as the new key
        delete res[keyEntry]; //delete old key
        res[name].splice(1, 0, count);
        return res;
    });
    arr.push(newArray);
}

如果我打印arr我会得到:

[ { 'social_profiles_2.social_profiles_1.social_profiles_0.id': [ 'social_profiles', 2, 1, 0, 'id' ] },
  { 'social_profiles_2.social_profiles_1.social_profiles_0.type': [ 'social_profiles', 2, 1, 0, 'type' ] },
  { 'social_profiles_2.social_profiles_1.social_profiles_0.url': [ 'social_profiles', 2, 1, 0, 'url' ] },
  { 'social_profiles_2.social_profiles_1.social_profiles_0.username': [ 'social_profiles', 2, 1, 0, 'username' ] } ]
然而,这不是我想要

的结果,我想要一个由 3 个键值数组组成的数组,一个包含social_profiles_0的东西,另一个包含social_profile_1的东西等。但是在我的循环中,它将所有内容连接在同一个数组中,例如"social_profiles_2.social_profiles_1.social_profiles_0.username",我似乎不明白为什么......

编辑:澄清它应该做什么。这是称为结果的对象,该函数将其作为输入

[ { id: [ 'social_profiles', 'id' ] },
{ type: [ 'social_profiles', 'type' ] },
{ url: [ 'social_profiles', 'url' ] },
{ username: [ 'social_profiles', 'username' ] } ]

结果应该是一个包含 3 个元素的数组,一个带有social_profiles_0元素,第二个元素social_profiles_1等。

你的代码存在一些问题(正如我在评论中指出的那样)。我意识到这不是代码审查堆栈交换,但我相信您无法从所有多余的东西中看到问题。这是您的原件,逐行细分:

var result = getData(item, keyName, true); // keyName? you don't show us
var arr = [];
for (var count = 0; count < 3; count++) {
  var tmpArray = result.slice(0); // this line is unnecessary, .map makes a copy for you and the zero doesn't do anything
  var newArray = tmpArray.map((res) => {
      var keyEntry = Object.keys(res)[0]; // only works if there's only one key
      const name = keyName + '_' + count + '.' + keyEntry; // const? why?
      res[name] = res[keyEntry]; // mutates the original? you'll mutate it again every time through the for loop
      delete res[keyEntry]; // same problem
      res[name].splice(1, 0, count); // same problem
      return res;
  });
  arr.push(newArray);
}

请注意,.slice.map 返回的副本是浅的,它不会克隆嵌套的对象/数组。一般来说,你会希望避免突变。

这是另一个人可能编写代码的方式(ES 6,但您使用了箭头函数和 const,所以......

for (var count = 0; count < 3; count++) {
  var array = result.map(res => {
    var keyEntry = Object.keys(res)[0];
    var name = `${keyName}_${count}.${keyEntry}`;
    // here we're returning a new object, no mutation, that has a
    // new array, no mutation (concat also returns a new array)
    return {
      // [name]: [count, ...res[keyEntry]] // updated per the comments
      [name]: res[keyEntry].concat([count]) // re-updated per comments
    };
  });
  arr.push(array);
}

首先,您是否使用 .slice(0) 创建结果数组的浅表副本?

我也认为这是由于线路

var keyEntry = Object.keys(res)[0];

res[name] = res[keyEntry]

当你执行该循环时,你会得到res obj的所有键。但是,第一次通过循环时,您添加一个新密钥,然后删除旧密钥。第二次通过循环,它抓住新创建的密钥(不是我认为您想要的下一个密钥)。你一遍又一遍地循环,但你永远不会在键中移动,只是一遍又一遍地改变第一个键。我认为这可能是奇怪串联的原因。

编辑:我不是 100% 关于您希望如何工作,但我认为这个代码片段是您可能会对代码的第一部分有所帮助的

for (var count = 0; count < 3; count++) {
var newArray = result.map((res) => {
    Object.keys(res).forEach(function(keyName){
        const name = keyName + '_' + count + '.' + keyEntry; 
        res[name] = res[keyEntry];
        delete res[keyEntry]; 
    })