這是我的目標:比較兩個物件并確定是否有 1 個或多個共同專案。如果有 1 個或多個共同點,則回傳,true否則(沒有共同點),回傳false.
當前問題:我正在嘗試將該.some()方法與來自 API 的 1 個物件和 1 個本地物件一起使用,但有點困惑為什么它不起作用……有什么想法嗎?它應該回傳 true,因為 John 在兩個物件中,但它回傳 false ??
代碼示例:在此示例中,它應該回傳true,因為 John 是物件 1(結果 1)和物件 2(結果 2)的名稱。但是,它回傳false。
有沒有人能幫助我理解我在這里做錯了什么?
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
const hasSimilarElement = result1.some((item) => item.name === result2.name);
console.log(hasSimilarElement);
uj5u.com熱心網友回復:
您的代碼失敗的原因是您試圖name在 result1 Array 的元素中找到 a 的匹配項result2.name
但是,result2它也是一個Array,陣列沒有一個.name恰好是所有.name與您正在搜索的元素匹配的元素 - 這不是它的作業原理
您需要迭代兩個陣列以查找匹配項
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
const hasSimilarElement = result1.some((item) => result2.some(item2 => item.name === item2.name));
console.log(hasSimilarElement);
.as-console-wrapper { min-height: 100%!important; top: 0; }
但是,對于非常大的結果集,這是低效的——我不是“大 O 表示法專家,但我相信這將是 O(n 2 )——你可能會比較result1.length*result2.length次
對于這種簡單的情況,您可以.name僅從兩個結果中提取,并創建一個Set... 如果Set大小小于組合結果.lengths,則意味著存在重復
在這里,您將對每個結果進行一次迭代 - 如果兩個集合都有 1000 個元素,即 2,000 次迭代,而使用上面的簡單方法則為 1,000,000
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
const hasSimilarElement = new Set([...result1, ...result2].map(({name}) => name)).size < result1.length result2.length
console.log(hasSimilarElement);
.as-console-wrapper { min-height: 100%!important; top: 0; }
但是,如果其中一個結果中存在重復名稱,則存在缺陷,這將無法按預期作業
這里每組迭代兩次 - 但是,給定 2 x 1,000 長的結果,4,000 次迭代仍然優于 1,000,000
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
const set1 = new Set(result1.map(({name}) => name));
const set2 = new Set(result2.map(({name}) => name));
const both = new Set([...set1, ...set2]);
const hasSimilarElement = both.size < set1.size set2.size;
console.log(hasSimilarElement);
.as-console-wrapper { min-height: 100%!important; top: 0; }
uj5u.com熱心網友回復:
Array.prototype.some() some() 方法測驗陣列中的至少一個元素是否通過了提供的函式實作的測驗。
在您的示例中,您試圖比較 2 個物件陣列。你有 false 因為 result2.name 未定義,你可能需要指定特定元素的索引,例如 result2[0].name
如果您想將 2 個陣列與一些陣列進行比較,您還需要遍歷 result2 項。你可以使用這樣的東西:
var result1 = [
{id:1, name:'Sandra', type:'user', username:'sandra'},
{id:2, name:'John', type:'admin', username:'johnny2'},
{id:3, name:'Peter', type:'user', username:'pete'},
{id:4, name:'Bobby', type:'user', username:'be_bob'}
];
var result2 = [
{id:2, name:'John', email:'[email protected]'},
{id:4, name:'Bobby', email:'[email protected]'}
];
const hasSimilarElement = result2.filter((item1) => !result1.some(item2 => item1.name === item2.name ));
console.log(hasSimilarElement);
uj5u.com熱心網友回復:
從上面的評論...
“OP需要
find一個具有相同item.name值的result1專案,result2而不是直接比較不存在的(因此undefined)name屬性result2。”
或者正如3limin4t0r正確建議的那樣,一個人可以再次換find另一個人some。
const result1 = [
{ id: 1, name: 'Sandra', type: 'user', username: 'sandra' },
{ id: 2, name: 'John', type: 'admin', username: 'johnny2' },
{ id: 3, name: 'Peter', type: 'user', username: 'pete' },
{ id: 4, name: 'Bobby', type: 'user', username: 'be_bob' },
];
const result2 = [
{ id: 5, name: 'Lea', email: '[email protected]' },
{ id: 2, name: 'John', email: '[email protected]' },
];
const result3 = [
{ id: 5, name: 'Lea', email: '[email protected]' },
];
const result4 = [];
console.log(
'similar elements within `result1` and `result2` ..?',
result1.some(itemA =>
result2.some(itemB => itemB.name === itemA.name)
)
);
console.log(
'similar elements within `result1` and `result3` ..?',
result1.some(itemA =>
result3.some(itemB => itemB.name === itemA.name)
)
);
console.log(
'similar elements within `result1` and `result4` ..?',
result1.some(itemA =>
result4.some(itemB => itemB.name === itemA.name)
)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
在下一次迭代中,一個原因可能會提出一個通用實作的函式,該函式允許自由選擇要比較的屬性名稱。
實作一個函式還提供了擺脫兩個嵌套some迭代的機會(盡管some為了成功比較而提前退出)。
在這里,人們將從較短的陣列中構建一個key(屬性名稱)特定的值索引(單個迭代任務),其中,在迭代較長的陣列時,將查找(不迭代)key專案相似度的特定值。
function hasSimilarItemsByKey(key, arrA, arrB) {
const [
// the shorter array will be the base
// for a `key` specific value index.
lookupArray,
// the longer array will be iterated
// and have its item `key` specific
// values looked up at a value index.
targetArray,
] = [
arrA,
arrB,
].sort((a, b) => a.length - b.length);
// create the object based value index
// (from the shorter array).
const valueIndex = lookupArray
.reduce((lookup, item) => {
const value = item[key];
lookup[value] ??= value;
return lookup;
}, Object.create(null)); // A `prototype`-less object. Thus,
// using the `in` operator is safe.
return targetArray.some(item => item[key] in valueIndex);
}
const result1 = [
{ id: 1, name: 'Sandra', type: 'user', username: 'sandra' },
{ id: 2, name: 'John', type: 'admin', username: 'johnny2' },
{ id: 3, name: 'Peter', type: 'user', username: 'pete' },
{ id: 4, name: 'Bobby', type: 'user', username: 'be_bob' },
];
const result2 = [
{ id: 5, name: 'Lea', email: '[email protected]' },
{ id: 2, name: 'John', email: '[email protected]' },
];
const result3 = [
// Attention,
// A matching `id` and a non matching `name`.
{ id: 1, name: 'Lea', email: '[email protected]' },
];
const result4 = [];
console.log(
'similar elements within `result1` and `result2`\n',
'...by `name`..?', hasSimilarItemsByKey('name', result1, result2),
'...by `id`..?', hasSimilarItemsByKey('id', result1, result2),
);
console.log(
'similar elements within `result1` and `result3`\n',
'...by `name`..?', hasSimilarItemsByKey('name', result1, result3),
'...by `id`..?', hasSimilarItemsByKey('id', result1, result3),
);
console.log(
'similar elements within `result1` and `result4`\n',
'...by `name`..?', hasSimilarItemsByKey('name', result1, result4),
'...by `id`..?', hasSimilarItemsByKey('id', result1, result4),
);
.as-console-wrapper { min-height: 100%!important; top: 0; }
uj5u.com熱心網友回復:
如果兩個陣列有一個共同的元素,那么從最短的陣列開始可能會更快找到它。不能保證,但我們可以針對最佳情況進行優化,例如
x=[1,2,3,4]
y=[4,5]
在這種情況下y.some(a => x.includes(a))比“更快”x.some(a => y.includes(a))
使用最長的陣列計算一組唯一值。
您可以創建一個函式,該函式采用用于查找的屬性名稱,然后是兩個陣列:
const checkBy = prop => (xs, ys) => {
let [long, short] = xs.length > ys.length ? [xs, ys] : [ys, xs];
long = new Set(long.map(x => x[prop]));
return short.some(x => long.has(x[prop]));
};
然后:
const checkByName = checkBy('name');
checkByName( [ {id: 1, name:'Sandra', type: 'user', username: 'sandra'}
, {id: 2, name: 'John', type: 'admin', username: 'johnny2'}
, {id: 3, name: 'Peter', type: 'user', username: 'pete'}
, {id: 4, name: 'Bobby', type: 'user', username: 'be_bob'}]
, [ {id: 2, name: 'John', email: '[email protected]'}
, {id: 4, name: 'Bobby', email: '[email protected]'}]);
//=> true
checkByName( [ {id: 1, name:'Sandra', type: 'user', username: 'sandra'}
, {id: 2, name: 'John', type: 'admin', username: 'johnny2'}
, {id: 3, name: 'Peter', type: 'user', username: 'pete'}
, {id: 4, name: 'Bobby', type: 'user', username: 'be_bob'}]
, [ {id: 2, name: 'xxxx', email: '[email protected]'}
, {id: 4, name: 'yyyyy', email: '[email protected]'}]);
//=> false
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/459680.html
標籤:javascript 数组 算法 迭代 比较
上一篇:從json中獲取父母,其中javascript中的字串
下一篇:根據陣列中的位置重復字符 1
