我看了一堆关于此的帖子,但似乎没有一个可以做我想做的事情,或者至少没有一个是我在搜索过程中发现的。
我有两个对象,我需要将两个对象合并而不覆盖任何属性。如果两个键相同,则需要连接它们的值。 示例:
$ python3 -m cProfile -s tottime test_smp_queues3.py
test1: building a large object and sending
BuildObject 5771.54 ms
SendObject 0.55 ms
test2: sending a bunch of small objects, lots of times
SendSmallObjects 22713.12 ms
Child process is ending
Test is finished
33418376 function calls (33417995 primitive calls) in 29.336 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
1000002 15.620 0.000 15.620 0.000 {method 'acquire' of '_multiprocessing.SemLock' objects}
4000000 2.468 0.000 5.793 0.000 random.py:174(randrange)
4000024 2.260 0.000 3.325 0.000 random.py:224(_randbelow)
1000002 1.883 0.000 19.981 0.000 queues.py:80(put)
4000000 1.126 0.000 6.919 0.000 random.py:218(randint)
组合对象
const base = {
icon: "icon--value1"
item: "item--value"
}
const extend = {
icon: "icon--value2"
item: "item--value"
list: "list--value"
}
我尝试使用es6 Assign和es6解构,但是它们只是覆盖了值。
const combined = {
icon: "icon--value1 icon--value2"
item: "item--value"
list: "list--value"
}
不是我追求的结果。有人知道我如何实现上述目标吗? 在此先感谢您的帮助。
答案 0 :(得分:2)
如果您乐于使用lodash(这也意味着不重新发明轮子),则可以使用here中记录的mergeWith()
函数。例如:
const base = {
icon: "icon--value1",
item: "item--value"
}
const extend = {
icon: "icon--value2",
item: "item--value",
list: "list--value"
}
const res = _.mergeWith(base, extend, (objVal, srcVal) =>
objVal && objVal !== srcVal ? `${objVal} ${srcVal}` : srcVal
)
console.log(res)
<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.11/lodash.min.js"></script>
或者,您可以通过执行以下操作来创建自己的mergeWith
:
const base = {
icon: "icon--value1",
item: "item--value"
}
const extend = {
icon: "icon--value2",
item: "item--value",
list: "list--value"
}
const customMergeWith = (a, b, proc) => {
const result = { ...a }
Object.keys(b).forEach(k => {
result[k] = proc(result[k], b[k])
})
return result
}
const res = customMergeWith(base, extend, (objVal, srcVal) =>
objVal && objVal !== srcVal ? `${objVal} ${srcVal}` : srcVal
)
console.log(res)
请注意,我个人更喜欢使用lodash版本,因为它更加健壮,并且您无需担心的代码更少。如果不需要,不要尝试重新发明轮子。
最后,人们似乎认为应该避免使用lodash之类的库,这可能是因为它们的大小。但是,这些天您只能导入所需的内容。有关详细信息,请参见以下答案:How to Import a Single Lodash Function?
答案 1 :(得分:1)
您可以使用reduce
来做到这一点。
这里的想法是:-
Set
。||
,否则,如果一个对象没有属性,则会返回undefined
并将其添加到不需要的输出)。然后我们将键和值添加到输出对象。
const base = {icon: "icon--value1",item: "item--value"}
const extend = {icon: "icon--value2",item: "item--value", list: "list--value"}
let keys = [...new Set([...Object.keys(base), ...Object.keys(extend)]) ]
let output = keys.reduce( (op, cur) => {
if((base[cur] && extend[cur]) && (base[cur] !== extend[cur])){
op[cur] = (base[cur]||'') + " " + (extend[cur]||'')
}
else {
op[cur] = base[cur] || extend[cur]
}
return op;
},{})
console.log(output)
实现Set
const base = {icon: "icon--value1",item: "item--value"}
const extend = {icon: "icon--value2",item: "item--value", list: "list--value"}
let keys = [...Object.keys(base), ...Object.keys(extend)]
let uniqueKeys = Object.keys(keys.reduce((output,cur)=>{
if( !output[cur] ){
output[cur]=''
}
return output;
},{}))
let output = uniqueKeys.reduce( (op, cur) => {
if((base[cur] && extend[cur]) && (base[cur] !== extend[cur])){
op[cur] = (base[cur]||'') + " " + (extend[cur]||'')
}
else {
op[cur] = base[cur] || extend[cur]
}
return op;
},{})
console.log(output)
答案 2 :(得分:0)
对我来说,这将是最易读的处理方式...
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.IO;
using System.Text;
using FastMember;
namespace BulkCopyTest
{
public class Program
{
public static void Main(string[] args)
{
const string filePath = "SOME FILE THAT YOU WANT TO LOAD TO A DB";
WriteData(GetData<dynamic>(filePath));
}
private static void WriteData<T>(IEnumerable<T> data)
{
using (var bcp = new SqlBulkCopy(GetConnection(), SqlBulkCopyOptions.TableLock, null))
using (var reader = ObjectReader.Create(data))
{
SetColumnMappings<T>(bcp.ColumnMappings);
bcp.BulkCopyTimeout = 300;
bcp.BatchSize = 150000;
bcp.DestinationTableName = ""; //TODO: Set correct TableName
bcp.WriteToServer(reader);
}
}
private static void SetColumnMappings<T>(SqlBulkCopyColumnMappingCollection mappings)
{
//Setup your column mappings
}
private static IEnumerable<T> GetData<T>(string filePath)
{
using (var fileStream = File.OpenRead(filePath))
using (var reader = new StreamReader(fileStream, Encoding.UTF8))
{
string line;
while ((line = reader.ReadLine()) != null)
{
//TODO: Add actual parsing logic and whatever else is needed to create an instance of T
yield return Activator.CreateInstance<T>();
}
}
}
private static SqlConnection GetConnection()
{
return new SqlConnection(new SqlConnectionStringBuilder
{
//TODO: Set Connection information here
}.ConnectionString);
}
}
}