比较多个对象值和操作节点,
Comparing multiple Object values and manipulating nodes,
预期功能: 创建一个 new 数组,该数组改变对象数组中的值。新值将是对象,其键 value
是原始值,另一个键 duplicate
是布尔值,如果该值与同一位置的其他对象值相同。
我试图循环数组,然后创建另一个数组,其中包含不是当前索引的索引。
创建一个不影响原始输入的深拷贝,然后循环原始数组,每次循环都会捕获当前对象的key。
我没有尝试更改任何比第一个范围更深的值,这就是为什么我只是改变 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 },
},
];
我不在整个重构之上,但被告知这太低效了,我已经尝试过不同的方法,这只是我得到的最接近的方法。
如果我对问题的理解正确,我相信这就是他们的目标。首先创建所有值的映射,然后将这些值插入输出数组。您遇到的麻烦是由于使用 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));
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');
可能有很多方法可以做到这一点...这就是我要做的...
感谢大家的帮助!我忘记指定一个边缘情况,其中节点值 可以 相同,并且不被认为是重复的,因为它们在对象中处于不同的位置。
我的回答还不是很有效,有时间我会尝试重构。然而,更重要的是这个功能的工作超过了它的性能。
这是我的工作
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;
};
又来了!谢谢!当人们回答我的问题时,我总是很兴奋
预期功能: 创建一个 new 数组,该数组改变对象数组中的值。新值将是对象,其键 value
是原始值,另一个键 duplicate
是布尔值,如果该值与同一位置的其他对象值相同。
我试图循环数组,然后创建另一个数组,其中包含不是当前索引的索引。
创建一个不影响原始输入的深拷贝,然后循环原始数组,每次循环都会捕获当前对象的key。
我没有尝试更改任何比第一个范围更深的值,这就是为什么我只是改变 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 },
},
];
我不在整个重构之上,但被告知这太低效了,我已经尝试过不同的方法,这只是我得到的最接近的方法。
如果我对问题的理解正确,我相信这就是他们的目标。首先创建所有值的映射,然后将这些值插入输出数组。您遇到的麻烦是由于使用 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));
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');
可能有很多方法可以做到这一点...这就是我要做的...
感谢大家的帮助!我忘记指定一个边缘情况,其中节点值 可以 相同,并且不被认为是重复的,因为它们在对象中处于不同的位置。
我的回答还不是很有效,有时间我会尝试重构。然而,更重要的是这个功能的工作超过了它的性能。
这是我的工作
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;
};
又来了!谢谢!当人们回答我的问题时,我总是很兴奋