通过知道对象的id在JSON中查找对象

Find object in JSON by knowing his id

本文关键字:对象 JSON 查找 id      更新时间:2023-09-26

我有一个对象数组,其中每个对象都有名称为linkedParts的子对象(请参见下面的示例),我如何根据子对象ID找到该子对象?

我已经使用了类似的东西来逐个对象ID查找对象,代码看起来像:

var updatedPart = axCalculation.selectedParts.filter(function( obj ) {
    return obj.id === response.data.id;
})[0];

然而,我不确定我是否可以搜索只知道子对象。如果是,如何?axCalculation.selectedParts外观类似:

[{
    "id": "1fccb481-53a0-400e-8831-80acd1793bee",
    "euroCode": "7812BGSHABW",
    "position": "REAR",
    "category": "REAR_WINDOW",
    "glassPartType": "GLASS",
    "description": "TODO: DECODE 7812BGSHABW",
    "calculatedPrice": 15768.00,
    "operation": "REPLACE",
    "selectionSource": "MANUAL",
    "linkedParts": []
}, {
    "id": "71e1dc3b-47a2-4406-970a-ef0911c93396",
    "euroCode": "7812AGSHMVZ",
    "position": "FRONT",
    "category": "FRONT_WINDOW",
    "glassPartType": "GLASS",
    "description": "TODO: DECODE 7812AGSHMVZ",
    "descriptionByUser": "TEST DESCC",
    "calculatedPrice": 5749.50,
    "priceByUser": 574.22,
    "operation": "REPLACE",
    "selectionSource": "MANUAL",
    "linkedParts": [{
        "id": "0f45cd6b-7053-4625-8ec9-87281c126e1d",
        "partNumber": "LSD",
        "description": "LEPÍCÍ SADA",
        "calculatedPrice": 562.50,
        "selectionSource": "AUTOMATIC",
        "enabled": true
    }, {
        "id": "61bbbdad-1838-4327-8c38-8808a35a403c",
        "partNumber": "string",
        "description": "GEL POD SENZOR",
        "calculatedPrice": 87.48,
        "selectionSource": "AUTOMATIC",
        "enabled": true
    }]
}]

您可以结合filtersome进行简单搜索。然而,这确实假设您想要搜索对象的子数组。

let find = (prop, by, where) => {
  return data.filter(d =>
    d[prop].some(sub => sub[by] === where)
  );
}

使用

console.log(find('linkedParts', 'id', '0f45cd6b-7053-4625-8ec9-87281c126e1d'));

很明显,我让它变得过于可配置,你可以传入每个属性,但如果你不需要,你可以硬编码。

fiddle编辑:忘了提fiddle使用ES6语法,我相信IE目前不支持。

一些文档

过滤文档

我看到的唯一有效返回linkedPart对象的答案是reduce/filter对象,但当我将所需的id更改为无效id时,我仍然会得到一些东西。所以这里是我要使用的版本。

编辑:我添加了一个证据,证明更改找到的对象就是更改初始对象

var selectedParts = [{
    "id": "1fccb481-53a0-400e-8831-80acd1793bee",
    "euroCode": "7812BGSHABW",
    "position": "REAR",
    "category": "REAR_WINDOW",
    "glassPartType": "GLASS",
    "description": "TODO: DECODE 7812BGSHABW",
    "calculatedPrice": 15768.00,
    "operation": "REPLACE",
    "selectionSource": "MANUAL",
    "linkedParts": []
}, {
    "id": "71e1dc3b-47a2-4406-970a-ef0911c93396",
    "euroCode": "7812AGSHMVZ",
    "position": "FRONT",
    "category": "FRONT_WINDOW",
    "glassPartType": "GLASS",
    "description": "TODO: DECODE 7812AGSHMVZ",
    "descriptionByUser": "TEST DESCC",
    "calculatedPrice": 5749.50,
    "priceByUser": 574.22,
    "operation": "REPLACE",
    "selectionSource": "MANUAL",
    "linkedParts": [{
        "id": "0f45cd6b-7053-4625-8ec9-87281c126e1d",
        "partNumber": "LSD",
        "description": "LEPÍCÍ SADA",
        "calculatedPrice": 562.50,
        "selectionSource": "AUTOMATIC",
        "enabled": true
    }, {
        "id": "61bbbdad-1838-4327-8c38-8808a35a403c",
        "partNumber": "string",
        "description": "GEL POD SENZOR",
        "calculatedPrice": 87.48,
        "selectionSource": "AUTOMATIC",
        "enabled": true
    }]
}];
//Search for the desired object(s)
var wantedId = "0f45cd6b-7053-4625-8ec9-87281c126e1d";
var linkedParts = [];
selectedParts.forEach(function(obj) {
  var foundLinkedParts = obj.linkedParts.filter(function(subObj) {
    return subObj.id == wantedId;
  });
  linkedParts = linkedParts.concat(foundLinkedParts);
});
console.log(linkedParts);
//Modify something in found object
linkedParts[0].partNumber = "My part number";
console.log(linkedParts[0].partNumber);
//Verify in object where initially stored
console.log(selectedParts[1]["linkedParts"][0].partNumber);

如果您想获得包含已定义id的"linkedPart"的对象:

var linkedPartId = "0f45cd6b-7053-4625-8ec9-87281c126e1d";
var objBasedOnLinkedPart = axCalculation.selectedParts.filter(function( obj ) {
    for (linkedPart in obj.linkedParts) {
        if (linkedPart.id === linkedPartId) {
            return true;
        }
    }
})[0];

您可以使用reduce来压平数组,然后使用filter来查找匹配结果:

function find(ary, subId) {
  return ary.reduce(function(prev, cur) {
    return prev.concat(cur.linkedParts);
  }, []).filter(function(item) { 
    return item.id == subId 
  })[0];
}

Array.reduce将获取所有linkedParts数组,并将它们放入一个数组中。Array.filter将返回与传递的值匹配的所有匹配项。

jsFiddle

上面是一个es5的实现,它在es6:中更漂亮

function find(ary, subId) {
  return ary.reduce((p,c) => p.concat(c.linkedParts), []).filter(i => i.id == subId)[0];
}