【问题标题】:Comparing multiple Object values and manipulating nodes,比较多个对象值和操作节点,
【发布时间】:2021-06-22 00:17:43
【问题描述】:

预期功能: 创建一个 数组,该数组会改变对象数组中的值。新值将是对象,其键 value 是原始值,另一个键 duplicate 是一个布尔值,如果该值与同一位置的其他对象值相同。

我正在尝试循环该数组,然后创建另一个包含不是当前索引的索引的数组。

在不影响原始输入的情况下创建一个深拷贝,然后循环原始数组,每次循环都会捕获当前对象的键。

我并没有试图改变任何比第一个范围更深的值,这就是我的原因,只是改变了typeof !== "object"

然后我设置当前索引,并且value 的新对象的键将保持原始值,但与当前索引相比,duplicate 将是其他索引的映射,然后使用.some 方法简化为单个布尔值。

深拷贝中的每个值都设置好后,return 它。

我目前正试图创建一个包含不是当前索引的索引的数组。

const testState = [
  {
    value1: "1",
    value2: "two",
    value3: 3,
  },
  {
    value1: "one",
    value2: 2,
    value3: "3",
  },
  {
    value1: "1",
    value2: 2,
    value3: "3",
  },
];

const testEquality = (accountArray) => {
  // Deep copy (shallow copies were letting values change)
  const returnedArray = JSON.parse(JSON.stringify(accountArray));

  accountArray.forEach((account) => {
    // assign an array that contains ever other index
    const otherIndexes = [];
    for (const key in account) {
      if (typeof key !== "object") {
        returnedArray[i][key] = {
          value: accountArray[i][key],
          // loop every other index, and compare to accountArray[i][key]
          // ex: otherIndexes.map(index => accountArray[index][key] === accountArray[i][key]).some(i => i)
          duplicate: false,
        };
      }
    }
  });

  return returnedArray;
};

testState = testState.map((obj) => testEquality(obj));

console.log(testState);
// output
[
  {
    value1: { value: "1", duplicate: true },
    value2: { value: "two", duplicate: false },
    value3: { value: 3, duplicate: false },
  },
  {
    value1: { value: "one", duplicate: false },
    value2: { value: 2, duplicate: true },
    value3: { value: "3", duplicate: true },
  },
  {
    value1: { value: "1", duplicate: true },
    value2: { value: 2, duplicate: true },
    value3: { value: "3", duplicate: true },
  },
];

我并没有超越整个重构,并且被告知这太低效了,我已经尝试了不同的方法,这只是我得到的最接近的方法。

【问题讨论】:

  • 这些说明听起来像是来自作业?如果是,请使用 blockquote 语法将它们格式化为引号。

标签: javascript reactjs ecmascript-6 logical-operators deep-copy


【解决方案1】:

如果我正确理解了这个问题,我相信这就是他们正在努力的方向。首先创建所有值的映射,然后将这些值插入输出数组。您遇到的麻烦是由于使用Array.some 进行了额外的循环。区别在于O(n)O(n^2)

const testState = [{
    value1: "1",
    value2: "two",
    value3: 3,
  },
  {
    value1: "one",
    value2: 2,
    value3: "3",
  },
  {
    value1: "1",
    value2: 2,
    value3: "3",
  },
];

function testEquality(array) {
  const copy = JSON.parse(JSON.stringify(array));
  const map = new Map();
  for (let i = 0; i < array.length; i++) {
    const values = Object.values(copy[i]);
    values.forEach(entry => {
      if (!map.has(entry)) {
        map.set(entry, false); // new value, not a duplicate
      } else {
        map.set(entry, true); // we've seen it before mark it as duplicate
      }
    });
  }
  for (let i = 0; i < copy.length; i++) {
    const entry = copy[i];
    for (const key in entry) {
      entry[key] = {
        value: array[i][key],
        duplicate: map.get(array[i][key])
      };
    }
  }
  return copy;
}

console.log(testEquality(testState));

【讨论】:

    【解决方案2】:

    const testState = [
      {
        value1: "1",
        value2: "two",
        value3: 3,
      },
      {
        value1: "one",
        value2: 2,
        value3: "3",
      },
      {
        value1: "1",
        value2: 2,
        value3: "3",
      },
    ];
    
    function transformData(array) {
    
      const { arr, duplicates } = array.reduce(({ arr, duplicates }, current) => {
        arr.push(
          Object.entries(current).map(([key, value]) => {
            duplicates.push(value);
            return [key, { value }];
          })
        );
    
        return {
          arr,
          duplicates,
        };
      }, { arr: [], duplicates: [] });
    
      return arr.reduce((finalArr, cur) => {
        finalArr.push(
          cur.reduce((obj, [nameKey, { value }]) => {
            const duplicatesQty = duplicates.filter(x => x === value).length;
            obj[nameKey] = { value, duplicate: duplicatesQty > 1 ? true : false };
            return obj;
          }, {})
        );
    
        return finalArr;
      }, []);
    }
    
    const test = [
      {
        value1: { value: "1", duplicate: true },
        value2: { value: "two", duplicate: false },
        value3: { value: 3, duplicate: false },
      },
      {
        value1: { value: "one", duplicate: false },
        value2: { value: 2, duplicate: true },
        value3: { value: "3", duplicate: true },
      },
      {
        value1: { value: "1", duplicate: true },
        value2: { value: 2, duplicate: true },
        value3: { value: "3", duplicate: true },
      },
    ];
    
    
    console.assert(JSON.stringify(test) === JSON.stringify(transformData(testState)), 'true assert, shouldnt print!');
    console.assert(JSON.stringify(test) !== JSON.stringify(transformData(testState)), 'validation confirmation, this should print');

    可能有很多方法可以做到这一点......这就是我会做的......

    【讨论】:

      【解决方案3】:

      感谢大家的帮助!我忘记指定节点值 可以 相同且不被视为重复的边缘情况,因为它们在对象中的不同位置。

      我的回答还不是很有效,有时间我会尝试重构。但是,更重要的是,此函数的工作效率高于其性能。

      这就是我要做的工作

      const testEquality = (accountArray) => {
        // deep copy to prevent original array from being effected
        const returnedArray = JSON.parse(JSON.stringify(accountArray));
      
        accountArray.forEach((account, i) => {
      
          // array that specifies every other index, besides this one
          const otherIndexes = accountArray
            .map((_, index) => index)
            .filter((index) => i !== index);
          
          for (const key in account) {
          
            // to keep this algorithm from leaving the scope 
            if (typeof key !== "object") {
          
              returnedArray[i][key] = {
                value: accountArray[i][key],
          
                // loop every other index, and compare to accountArray[i][key]
                duplicate: otherIndexes
                  .map((index) => accountArray[index][key] === accountArray[i][key])
                  .some((i) => i),
              };
      
            }
          }
        });
      
        return returnedArray;
      };
      

      再来一次!谢谢!当人们回答我的问题时,我总是很兴奋?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-23
        • 2019-02-25
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多