给出两个数组:
public static string ConvertDataTableToHTMLExtra(DataTable dt)
{
string html = "";
html += "<table>";
//add header row
html += "<thead>";
html += "<tr>";
for (int i = 0; i < dt.Columns.Count; i++)
html += "<td>" + dt.Columns[i].ColumnName + "</td>";
html += "</tr>";
html += "</thead>";
//add rows
for (int i = 0; i < dt.Rows.Count; i++)
{
html += "<tr>";
for (int j = 0; j < dt.Columns.Count; j++)
html += "<td>" + dt.Rows[i][j].ToString() + "</td>";
html += "</tr>";
}
html += "</table>";
return html;
}
我正在尝试根据const inputOne = [
{id: "valueA", prop: 123},
{id: "valueB", prop: 456}
]
const inputTwo = [
{id: "valueA", other: 54},
{id: "valueB", other: 98},
{id: "valueC", other: 11}
]
的{{1}}过滤inputTwo
,然后合并在两者中找到的属性。
所需的输出:
inputOne
我已经尝试过id
,combinedAndFiltered = [
{id: "valueA", other: 54, prop: 123},
{id: "valueB", other: 98, prop: 456}
]
和/或map
的各种组合,但不知何故无法解决。
答案 0 :(得分:1)
使用Map将第一个数组转换为Array.reduce()
,然后缩小第二个数组,如果在Map中找到了对象,则从Map中获取对象,合并对象,然后添加到累加器:
const combine = (arr1, arr2) => {
const arr1Map = arr1.reduce((m, o) => m.set(o.id, o), new Map)
return arr2.reduce((r, o) => arr1Map.has(o.id) ?
[...r, { ...o, ...arr1Map.get(o.id) }] : r
, [])
}
const inputOne = [{id: "valueA", prop: 123},{id: "valueB", prop: 456}]
const inputTwo = [{id: "valueA", other: 54},{id: "valueB", other: 98},{id: "valueC", other: 11}]
const result = combine(inputOne, inputTwo)
console.log(result)
答案 1 :(得分:1)
这应该可以解决问题(假设inputOne
就像源代码一样);
const inputOne = [
{id: "valueA", prop: 123},
{id: "valueB", prop: 456}
]
const inputTwo = [
{id: "valueA", other: 54},
{id: "valueB", other: 98},
{id: "valueC", other: 11}
]
const mergeArrays = (first, second) => {
return first.map((firstItem) => {
const obj = second.find((secondItem) => secondItem.id === firstItem.id);
return {...firstItem, ...obj};
});
};
const combinedArrays = mergeArrays(inputOne, inputTwo);
console.log(combinedArrays);
答案 2 :(得分:1)
此解决方案假定只有两个集合,并且id
属性在每个集合中都是唯一的。
您可以通过以下方式基于共同属性(id
)创建an intersection的两组合并对象:
此方法返回一个新集合,其中包含在两个集合中都找到的合并对象。如果任一集合中缺少对象,则该对象将不包含在输出中。
const inputOne = [ {id: "valueA", prop: 123}, {id: "valueB", prop: 456}, {id: "valueD", prop: 789} ]
const inputTwo = [ {id: "valueA", other: 54}, {id: "valueB", other: 98}, {id: "valueC", other: 11} ]
function intersectAndMerge(a, b) {
const accumulator = []
for(let { id, ...props } of a) {
const match = b.find(e => e.id === id)
if(match !== undefined) {
accumulator.push({ ...match, ...props })
}
}
return accumulator
}
console.log(intersectAndMerge(inputOne, inputTwo))
这也可以通过reduce循环来完成,但是我发现它的可读性较差:
const inputOne = [ {id: "valueA", prop: 123}, {id: "valueB", prop: 456}, {id: "valueD", prop: 789} ]
const inputTwo = [ {id: "valueA", other: 54}, {id: "valueB", other: 98}, {id: "valueC", other: 11} ]
function intersectAndMerge(a, b) {
return a.reduce((accumulator, { id, ...props }) => {
const match = b.find(e => e.id === id)
if(match !== undefined) {
accumulator.push({ ...match, ...props })
}
return accumulator
}, [])
}
console.log(intersectAndMerge(inputOne, inputTwo))
答案 3 :(得分:0)
inputOne.map((a, i) => ({...a, ...inputTwo[i]}))
它假设inputOne是较短的那个,您可以使用if
来确保在所有情况下都是正确的。
编辑:
在真正的功能问题上,人们可能会在haskell中使用zip
之类的东西,但是恐怕如果没有进一步的库或自己实现它,恐怕就会陷入类似的情况。
编辑2:
inputOne.map((a, i) => ({...a, ...(inputTwo.filter(x => x.id === a.id)[0])}))
此功能基于id
属性,但阅读效果不够好。
答案 4 :(得分:0)
使用for
的简单解决方案:
// declare an empty array:
let resArr = []
for(i=0; i<inputOne.length; i++) {
for(j=0; j<inputTwo.length; j++) {
if(inputOne[i].id === inputTwo[j].id) {
resArr.push({ ...inputOne[i], ...inputTwo[j] })
}
}
}
答案 5 :(得分:0)
您可以使用地图和过滤器解决此问题。如果我对您想要的内容没有错,这可能会有所帮助
let result = inputOne.map((item) => {
let leftItems = inputTwo.filter((item2) => {
return item2.id == item.id
})
if(leftItems.length > 0) {
return {id: item.id, other: leftItems[0].other, prop: item.prop}
// or return {...item, ...leftItems[0]}
}
}).filter(item => !! item)
答案 6 :(得分:0)
好吧,您可以首先构建一个Object并使用它获取其他值,同时使用.map
遍历另一个数组
const inputOne = [
{id: "valueA", prop: 123},
{id: "valueB", prop: 456}
],
inputTwo = [
{id: "valueA", other: 54},
{id: "valueB", other: 98},
{id: "valueC", other: 11}
],
ids = {};
inputTwo.forEach(function (o) {
ids[o.id] = o;
});
var res = inputOne.map(function (o) {
return {
other: ids[o.id].other,
prop: o.prop,
id: o.id
};
});
console.log(res)
答案 7 :(得分:0)
我认为几乎所有解决方案都将进行某种形式的双重迭代,无论是通过for循环,映射还是过滤器。与上面列出的方法不同的另一种方法是使用像lodash这样的库。 This answer already gives a pretty good example of the unionBy
function。