打字稿:如果条件为真,则在数组中添加项目

时间:2019-07-02 07:10:33

标签: arrays typescript

我想使用另一个数组finalObject.members中的值来填充数组allParticipants。第二个数组(allParticipants)如下:

allParticipants = [
    { 
        uid:"mem1_100_00",
        member: "mem1",
        tontine: "100"
        total: 785
    },
    { 
        uid:"mem1_100_01",
        member: "mem1",
        tontine: "100"
        total: 800
    },
    { 
        uid:"mem1_200_00",
        member: "mem1",
        tontine: "200"
        total: 1000
    },
    {
        uid:"mem2_100_00",
        member: "mem2",
        tontine: "100"
        total: 200
    },
    { 
        uid:"mem2_200_00",
        member: "mem2",
        tontine: "200"
        total: 7850
    },
    { 
        uid:"mem2_200_01",
        member: "mem2",
        tontine: "200"
        total: 5000
    },
    { 
        uid:"mem2_200_02",
        member: "mem2",
        tontine: "200"
        total: 1600
    },
    { 
        uid:"mem3_100_00",
        member: "mem3",
        tontine: "100"
        total: 150
    },
    { 
        uid:"mem3_100_01",
        member: "mem3",
        tontine: "100"
        total: 0
    },
    { 
        uid:"mem3_200_00",
        member: "mem3",
        tontine: "200"
        total: 2500
    }

]

插入后,第一个数组(finalObject.members)应该看起来像这样:

finalObject.members = [
    { 
        uid: "mem1",
        tontines: {
            100:[
                {
                    uid: "mem1_100_00",
                    total:785
                },
                {
                    uid: "mem1_100_01",
                    total:800
                },
            ],
            200:[
                {
                    uid: "mem1_200_00",
                    total:1000
                }
              ]
        }
    },
    { 
        uid: "mem2",
        tontines: {
            100: [
                {
                    uid: "mem2_100_00",
                    total: 200
                }
            ],
            200:[
                {
                    uid: "mem2_200_00",
                    total: 7850
                },
                {
                    uid: "mem2_200_01",
                    total: 5000
                },
                {
                    uid: "mem2_200_02",
                    total: 1600
                }
            ]
        }
    },
    { 
        uid: "mem3",
        tontines: {
            100: [
                {
                    uid: "mem3_100_00",
                    total: 150                
                },
                {
                    uid: "mem3_100_01",
                    total: 0                
                }
            ],
            200:[
                {
                    uid: "mem3_200_00",
                    total: 2500        
                }
            ]
        }
    }
]

所以我写了这段代码:

const sizMem    = finalObject.members.length;
const sizPartp  = allParticipants.length;

for(let idx1=0; idx1<sizPartp; idx1++){
    let partP = allParticipants[idx1]
    for(let idx2=0; idx2<sizMem; idx2++){
        let memP = finalObject.members[idx2];
        if(partP.member.localeCompare(memP.uid) == 0){
            finalObject.members[idx2].tontines[partP.tontine].push({
                uid:     partP.uid,
                total:   partP.total,
            })
            break
        }
    }
}

但这就是我得到的:

finalObject.members = [
    { 
        uid: "mem1",
        tontines: {
            100:[
                {
                    uid: "mem1_100_00",
                    total:785
                },
                {
                    uid: "mem1_100_01",
                    total:800
                },
                {
                    uid: "mem2_100_00",
                    total: 200
                },
                {
                    uid: "mem3_100_00",
                    total: 150                
                },
                {
                    uid: "mem3_100_01",
                    total: 0                
                }                    
            ],
            200:[
                {
                    uid: "mem1_200_00",
                    total:1000
                },
                {
                    uid: "mem2_200_00",
                    total: 7850
                },
                {
                    uid: "mem2_200_01",
                    total: 5000
                },
                {
                    uid: "mem2_200_02",
                    total: 1600
                },
                {
                    uid: "mem3_200_00",
                    total: 2500        
                }                    
              ]
        }
    },
    { 
        uid: "mem2",
        tontines: {
            100:[
                {
                    uid: "mem1_100_00",
                    total:785
                },
                {
                    uid: "mem1_100_01",
                    total:800
                },
                {
                    uid: "mem2_100_00",
                    total: 200
                },
                {
                    uid: "mem3_100_00",
                    total: 150                
                },
                {
                    uid: "mem3_100_01",
                    total: 0                
                }                    
            ],
            200:[
                {
                    uid: "mem1_200_00",
                    total:1000
                },
                {
                    uid: "mem2_200_00",
                    total: 7850
                },
                {
                    uid: "mem2_200_01",
                    total: 5000
                },
                {
                    uid: "mem2_200_02",
                    total: 1600
                },
                {
                    uid: "mem3_200_00",
                    total: 2500        
                }                    
              ]
        }
    },
    { 
        uid: "mem3",
        tontines: {
            100:[
                {
                    uid: "mem1_100_00",
                    total:785
                },
                {
                    uid: "mem1_100_01",
                    total:800
                },
                {
                    uid: "mem2_100_00",
                    total: 200
                },
                {
                    uid: "mem3_100_00",
                    total: 150                
                },
                {
                    uid: "mem3_100_01",
                    total: 0                
                }                    
            ],
            200:[
                {
                    uid: "mem1_200_00",
                    total:1000
                },
                {
                    uid: "mem2_200_00",
                    total: 7850
                },
                {
                    uid: "mem2_200_01",
                    total: 5000
                },
                {
                    uid: "mem2_200_02",
                    total: 1600
                },
                {
                    uid: "mem3_200_00",
                    total: 2500        
                }                    
              ]
        }
    }
]

因此,它将为每个成员添加所有元素,而不是仅将新元素添加到相应成员。我已经检查了if条件(但是将结果写到控制台中),在那部分上一切正常。仅当member的{​​{1}}属性与Participant的{​​{1}}属性相同时才执行插入。但是,它到处都增加了新元素!

我哪里出错了?

2 个答案:

答案 0 :(得分:0)

  

我哪里出错了?

  1. 您的代码太复杂。尝试通过2个嵌入式循环一次完成所有操作。当不需要索引时,使用索引代替(for ... of)。

  2. 更精确的诊断:一次按下即可,您必须在其中添加

    • 新成员
    • 会员的新tontines
    • 会员参加tontine的新活动

首先对成员ID进行索引/分组,然后对tontine-id进行索引应该会有所帮助。

var participations = {}
for (let  p of allParticipations) {
    let member = p.member
    if ( ! (member in participations)) 
          participations[member] = { "member": member, "tontines" : {} }
    }  
    let tontine = p.tontine
    if ( ! (tontine in participations[member].tontines)) {
          participations[member].tontines[tontine] = [] 
    }
    participations[member].tontines[tontine].push( { "uid": p.uid, "total": p.total })
}

产生此:

{ 
  mem1: { member: 'mem1', tontines: { '100': [Array], '200': [Array] } },
  mem2: { member: 'mem2', tontines: { '100': [Array], '200': [Array] } },
  mem3: { member: 'mem3', tontines: { '100': [Array], '200': [Array] } } 
}

索引避免了搜索循环。然后,很容易从参与变量中构建所需的内容。


编辑:可以将这种中间数据结构简化为列表的双索引字典

var participations = {}
for (let p of allParticipations) {
    if ( ! (p.member in participations)) participations[p.member] = {}
    if ( ! (p.tontine in participations[p.member])) participations[p.member][p.tontine] = [] 
    participations[p.member][p.tontine].push({ "uid": p.uid, "total": p.total })
}

结果:

{ 
  mem1: { '100': [ [Object], [Object] ], '200': [ [Object] ] },
  mem2: { '100': [ [Object] ], '200': [ [Object], [Object], [Object] ] },
  mem3: { '100': [ [Object], [Object] ], '200': [ [Object] ] } 
}

编辑2:有时,通用多级索引功能会以更具功能性的风格提供帮助。喜欢:

var x = indexBy(allParticipations,
        [ p => p.member, p => p.tontine ],    // keys
        p => ({ "uid" : p.uid,                // items
               "total" : p.total
              })
           )

源代码:

function indexBy(data, extractors, finalizer) {
    let all_but_last = extractors.slice(0, extractors.length-1)
    let last = extractors[extractors.length-1]

    let result = {} 
    for (let item of data) {
        let node = result
        for (let extractor of all_but_last) {
            let key = extractor(item)
            if ( !(key in node)) node[key] = {}  // indexing all the way down
            node = node[key]
        }
        let key = last(item)
        if ( !(key in node)) node[key] = []   // last level is an array
        node[key].push(finalizer(item))
    }
    return result   
}

答案 1 :(得分:0)

无耻的插头。我的小型无依赖库blinq非常适合这类转换。

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.11" 

const output = blinq(allParticipants)
  .groupBy(x => x.member)
  .select(g => ({
    uid: g.key,
    member: Object.fromEntries(
      g
      .groupBy(x => x.tontine)
      .select(gg => [
        gg.key,
        gg.select(x => ({
          uid: x.uid,
          total: x.total
        })).toArray()
      ])
      .toArray()
    )
  }))
  .toArray();
const {
  blinq
} = window.blinq
const allParticipants = [{
    uid: "mem1_100_00",
    member: "mem1",
    tontine: "100",
    total: 785
  },
  {
    uid: "mem1_100_01",
    member: "mem1",
    tontine: "100",
    total: 800
  },
  {
    uid: "mem1_200_00",
    member: "mem1",
    tontine: "200",
    total: 1000
  },
  {
    uid: "mem2_100_00",
    member: "mem2",
    tontine: "100",
    total: 200
  },
  {
    uid: "mem2_200_00",
    member: "mem2",
    tontine: "200",
    total: 7850
  },
  {
    uid: "mem2_200_01",
    member: "mem2",
    tontine: "200",
    total: 5000
  },
  {
    uid: "mem2_200_02",
    member: "mem2",
    tontine: "200",
    total: 1600
  },
  {
    uid: "mem3_100_00",
    member: "mem3",
    tontine: "100",
    total: 150
  },
  {
    uid: "mem3_100_01",
    member: "mem3",
    tontine: "100",
    total: 0
  },
  {
    uid: "mem3_200_00",
    member: "mem3",
    tontine: "200",
    total: 2500
  }
];
const output = blinq(allParticipants)
  .groupBy(x => x.member)
  .select(g => ({
    uid: g.key,
    member: Object.fromEntries(
      g
      .groupBy(x => x.tontine)
      .select(gg => [
        gg.key,
        gg.select(x => ({
          uid: x.uid,
          total: x.total
        })).toArray()
      ])
      .toArray()
    )
  }))
  .toArray();
console.log(JSON.stringify(output, null, 2));