在 Svelte 中,如何可靠地合并这两个数组中的对象并循环生成的数组?
How can I reliably merge objects from these 2 arrays and loop the resulting array, in Svelte?
我有 2 个对象数组,每个对象都包含我希望合并的信息。数组有一个公共键:
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
]
我把上面的数组合并成一个 new 这样的:
let merged = countries.map((item, i) => Object.assign({}, item, dial[i]));
然后我使用 Svelte 在 table 中显示信息:
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Code</th>
<th>Dial Code</th>
</tr>
</thead>
<tbody>
{#if countries.length}
{#each merged as m}
<tr>
<td>{m.name}</td>
<td>{m.code}</td>
<td>{m.dial_code}</td>
</tr>
{/each}
{:else}
<tr>
<td colspan="3">There are no countries</td>
</tr>
{/if}
</tbody>
</table>
该方法的工作原理可以看出 here,但不是“防弹”:如果对象的顺序不同,则按 code
键,方法 returns bad/false 个结果。
即使 dial
数组如下所示,哪种方法也有效?
let dial = [
{ code: "IL", dial_code: "+972" },
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
]
一种方法是使用 reduce
,将两个数组合并为一个数组,然后从中获取 Object.values。这是一个例子:
var dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" },];
var countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" },{ code: "IL", name: "Israel" }];
var result = Object.values([...dial, ...countries].reduce((acc, elem)=>{
acc[elem.code] = {...(acc[elem.code] || {}), ...elem};
return acc;
},{}));
console.log(result);
或者您也可以使用 map
和 find
:
var dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" },];
var countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" },{ code: "IL", name: "Israel" }];
var result= countries.map(country=>({...country, dialo_code:dial.find(p=>p.code==country.code)?.dial_code}));
console.log(result);
这是不同的方法
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
{ code: "ILi", dial_code: "+972" }
]
result=[]
dial.forEach((x)=>{
countries.forEach(o=>{
if(x.code==o.code)
return result.push(Object.assign({},o,x))
})
})
console.log(result)
这里的一些答案本质上是使用嵌套循环(forEach
内的 forEach
,或 map
内的 find
。在这种情况下这可能没问题,但这种方法的性能是 O(n^2),这是一个危险信号。如果你有一个 third 数据数组,你想用类似的方法合并,它将变成 O(n^3),依此类推。
一个更具扩展性的解决方案是使用查找:
const sources = [countries, dial]; // plus anything you add in future!
const codes = new Set( // using a set is an easy way to dedupe
sources.map(source => source.map(d => d.code)).flat()
);
const lookups = sources.map(source => {
const lookup = new Map();
source.forEach(d => lookup.set(d.code, d));
return lookup;
});
const combined = Array.from(codes, code => {
return Object.assign({}, ...lookups.map(d => d.get(code) || {}));
});
我认为排序比使用内置数据结构更有效。
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
]
const combine = (arr1, arr2) => {
const combined = arr1.concat(arr2)
combined.sort((x, y) => x.code.localeCompare(y.code))
const result = [combined[0]]
for (let i = 1; i < combined.length; i++) {
if (combined[i].code == combined[i - 1].code) {
result[result.length - 1] = { ...result[result.length - 1], ...combined[i] }
} else {
result.push(combined[i])
}
}
return result
}
console.log(combine(countries, dial))
我有 2 个对象数组,每个对象都包含我希望合并的信息。数组有一个公共键:
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
]
我把上面的数组合并成一个 new 这样的:
let merged = countries.map((item, i) => Object.assign({}, item, dial[i]));
然后我使用 Svelte 在 table 中显示信息:
<table class="table table-bordered">
<thead>
<tr>
<th>Name</th>
<th>Code</th>
<th>Dial Code</th>
</tr>
</thead>
<tbody>
{#if countries.length}
{#each merged as m}
<tr>
<td>{m.name}</td>
<td>{m.code}</td>
<td>{m.dial_code}</td>
</tr>
{/each}
{:else}
<tr>
<td colspan="3">There are no countries</td>
</tr>
{/if}
</tbody>
</table>
该方法的工作原理可以看出 here,但不是“防弹”:如果对象的顺序不同,则按 code
键,方法 returns bad/false 个结果。
即使 dial
数组如下所示,哪种方法也有效?
let dial = [
{ code: "IL", dial_code: "+972" },
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
]
一种方法是使用 reduce
,将两个数组合并为一个数组,然后从中获取 Object.values。这是一个例子:
var dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" },];
var countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" },{ code: "IL", name: "Israel" }];
var result = Object.values([...dial, ...countries].reduce((acc, elem)=>{
acc[elem.code] = {...(acc[elem.code] || {}), ...elem};
return acc;
},{}));
console.log(result);
或者您也可以使用 map
和 find
:
var dial = [ { code: "IL", dial_code: "+972" }, { code: "AF", dial_code: "+93" }, { code: "AL", dial_code: "+355" },];
var countries = [ { code: "AF", name: "Afghanistan" }, { code: "AL", name: "Albania" },{ code: "IL", name: "Israel" }];
var result= countries.map(country=>({...country, dialo_code:dial.find(p=>p.code==country.code)?.dial_code}));
console.log(result);
这是不同的方法
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
{ code: "ILi", dial_code: "+972" }
]
result=[]
dial.forEach((x)=>{
countries.forEach(o=>{
if(x.code==o.code)
return result.push(Object.assign({},o,x))
})
})
console.log(result)
这里的一些答案本质上是使用嵌套循环(forEach
内的 forEach
,或 map
内的 find
。在这种情况下这可能没问题,但这种方法的性能是 O(n^2),这是一个危险信号。如果你有一个 third 数据数组,你想用类似的方法合并,它将变成 O(n^3),依此类推。
一个更具扩展性的解决方案是使用查找:
const sources = [countries, dial]; // plus anything you add in future!
const codes = new Set( // using a set is an easy way to dedupe
sources.map(source => source.map(d => d.code)).flat()
);
const lookups = sources.map(source => {
const lookup = new Map();
source.forEach(d => lookup.set(d.code, d));
return lookup;
});
const combined = Array.from(codes, code => {
return Object.assign({}, ...lookups.map(d => d.get(code) || {}));
});
我认为排序比使用内置数据结构更有效。
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" },
]
let dial = [
{ code: "AF", dial_code: "+93" },
{ code: "AL", dial_code: "+355" },
{ code: "IL", dial_code: "+972" },
]
const combine = (arr1, arr2) => {
const combined = arr1.concat(arr2)
combined.sort((x, y) => x.code.localeCompare(y.code))
const result = [combined[0]]
for (let i = 1; i < combined.length; i++) {
if (combined[i].code == combined[i - 1].code) {
result[result.length - 1] = { ...result[result.length - 1], ...combined[i] }
} else {
result.push(combined[i])
}
}
return result
}
console.log(combine(countries, dial))