根据另一个数组在数组中搜索元素并更改属性

时间:2019-05-28 08:06:17

标签: javascript typescript ecmascript-6

我有两个这样的对象数组:

const officers: any[] = [
  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'Admiral Ozzel' },
  { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor: any[] = [
  { id: 56, name: 'New Name', additionalData: 1 },
];

我想从searchAndChangeFor的{​​{1}}中查找元素并修改内容。通常,如果我有一个元素,我可以这样做:

officers

但是我需要按数组而不是单个元素进行搜索,所以我已经尝试过但没有成功:

officers.map((item) => {
    // I want to modify id: 56 and update officers here.
    item.id === 56 ? { ...item, name: 'Change name for 56' } : item
}); 

预期输出:

officers.map((item) => {
   searchAndChangeFor.find((item2) => {
       item.id === item2.id? { ...item, name: 'Change name for 56' } : item
   }); 
}); 

它对数组很疯狂。如何基于 { id: 20, name: 'Captain Piett' }, { id: 24, name: 'General Veers' }, { id: 56, name: 'New Name', additionalData: 1 }, { id: 88, name: 'Commander Jerjerrod' } officers中查找元素并更改其名称?我也想将所有其他现有物品保留在军官中。

6 个答案:

答案 0 :(得分:3)

您可以map排列人员。使用findid中获得具有相同searchAndChangeFor的对象。使用传播语法合并它们

如果您只想合并,就可以做

return { ...item, ...searchAndChangeFor.find(o => o.id === item.id) } 

但是,如果要在找到匹配项时添加新属性,则可以有条件地返回如下内容:

const officers=[{id:20,name:'Captain Piett'},{id:24,name:'General Veers'},{id:56,name:'Admiral Ozzel'},{id:88,name:'Commander Jerjerrod'}],
    searchAndChangeFor = [{id:56,name:'New Name',additionalData:1},];
    
const output = officers.map(item => {
  const found = searchAndChangeFor.find(o => o.id === item.id);
  if (found)
    return { ...item, ...found, newProperty: 'value' }
  else
    return item;
})

console.log(output)

另一种选择是克隆officers数组以避免突变,而通过searchAndChangeFor循环(因为它是较小的数组)

const officers=[{id:20,name:'Captain Piett'},{id:24,name:'General Veers'},{id:56,name:'Admiral Ozzel'},{id:88,name:'Commander Jerjerrod'}],
    searchAndChangeFor = [{id:56,name:'New Name',additionalData:1},],
    output = [...officers];

searchAndChangeFor.forEach(s => {
  const index = officers.findIndex(o => o.id === s.id);
  output[index] = Object.assign({}, output[index], s)
})

console.log(output)

答案 1 :(得分:1)

您可以找到该项目并使用找到的名称进行更改,或者不更改而退回该项目。

const
    officers = [{ id: 20, name: 'Captain Piett' }, { id: 24, name: 'General Veers' }, { id: 56, name: 'Admiral Ozzel' }, { id: 88, name: 'Commander Jerjerrod' }],
    searchAndChangeFor = [{ id: 56, name: 'New Name', additionalData: 1 }],
    result = officers.map((item) => {
        let temp = searchAndChangeFor.find((item2) => item.id === item2.id); 
        return temp ? { ...item, name: temp.name } : item;
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 2 :(得分:1)

find期望布尔响应,当接收到true时,它将返回为其返回true的项目,您正尝试直接在find回调主体中对项目进行突变。这不是您需要做的,您只想更改searchAndChangeFor中用于数组的id所在的值。

const ids = searchAndChangeFor.map((rel) => rel.id);
const changed = officers.map((item) => ids.includes(item.id) ?
    {{ Item mutation logic here }} :
    item);

答案 3 :(得分:1)

假设您要保留officerssearchAndChangeFor对象的所有属性:

const officers = [
    { id: 20, name: 'Captain Piett' },
    { id: 24, name: 'General Veers' },
    { id: 56, name: 'Admiral Ozzel', admiralSince: 2008 },
    { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor = [
    { id: 56, name: 'New Name', additionalData: 1 },
];

const newOfficers = officers.map(officer => {
    const changedOfficer = searchAndChangeFor.find(changedOfficer => changedOfficer.id === officer.id)
    return changedOfficer ? { ...officer, ...changedOfficer } : officer;
});

console.log(newOfficers);

答案 4 :(得分:0)

您的代码存在的问题是.map希望您返回要存储在结果数组中的值,而不返回任何内容。

您可以保留searchAndChangeFor的所有ID组成的数组。只会计算一次,因此效率很高,并且与officer.id中的.map相比更容易。

const officers = [
  { id: 20, name: 'Captain Piett' },
  { id: 24, name: 'General Veers' },
  { id: 56, name: 'Admiral Ozzel' },
  { id: 88, name: 'Commander Jerjerrod' }
];

const searchAndChangeFor = [
  { id: 56, name: 'Admiral Ozzel' },
];

const allIDsToChange = searchAndChangeFor.map(el => el.id);
const newOfficers = officers.map((item) => allIDsToChange.includes(item.id) ? { ...item,
  name: 'Change name for 56'
} : item);

console.log(newOfficers);

答案 5 :(得分:-2)

您可以找到该项目,如果找到该项目,请更改名称并返回更改的项目或简单地返回项目(无更改)

public HBox getBox() throws Exception {
        HBox hb = new HBox();
        hb.getChildren().clear();

        // Add nodes to hbox
        for (int i = 1; i <= 3; i++) {
            hb.setRotate(45 * i);
            hb.getChildren().add(new ImageView(new Image(new FileInputStream("myFile.png"))));
        }
        return hb;
    }