通过知道他的 ID 在 JSON 中找到对象

Find object in JSON by knowing his id

我有一个对象数组,其中每个对象都有名称为 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 目前不支持。

some docs

filter docs

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

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 将 return 所有匹配传递值的匹配项。

jsFiddle

以上是es5的实现,在es6中更漂亮:

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

我看到 return 有效链接部件对象的唯一答案是 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);