Tengo una matriz de objetos, donde cada objeto tiene subobjetos con el nombre linkedParts (vea el ejemplo a continuación), ¿cómo puedo encontrar ese subobjeto basado en la ID del subobjeto?

Ya usé algo similar para buscar objeto por ID de objeto y el código se ve así:

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

Sin embargo, no estoy seguro si puedo buscar solo conociendo subobjetos. Si es así, ¿cómo? axCalculation.selectedParts se parece a:

[{
    "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
    }]
}]
-1
Andurit 12 may. 2016 a las 15:16

4 respuestas

La mejor respuesta

La única respuesta que vi que devuelve efectivamente el objeto vinculadoPart es reducir / filtrar, pero cuando cambio la identificación deseada por una no válida, todavía obtengo algo. Así que aquí la versión que usaría.

EDITAR: agregué una prueba de que cambiar el objeto encontrado está cambiando el inicial

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);
1
Master DJon 12 may. 2016 a las 12:46

Puede usar reducir para aplanar la matriz y luego usar filtro para encontrar el resultado coincidente:

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 tomará todas las matrices vinculadas y las colocará en una matriz. Array.filter devolverá todas las coincidencias que coincidan con el valor pasado.

jsFiddle

Lo anterior fue una implementación de es5, es mucho más bonita en es6:

function find(ary, subId) {
  return ary.reduce((p,c) => p.concat(c.linkedParts), []).filter(i => i.id == subId)[0];
}
1
Daniel Gimenez 13 may. 2016 a las 12:57

Si desea obtener los objetos que contienen una "parte vinculada" de una identificación definida:

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];
1
Brewal 12 may. 2016 a las 12:23

Puede realizar una búsqueda simple combinando filter y some. Sin embargo, esto supone que desea buscar una submatriz de objetos.

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

Uso

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

Obviamente lo he hecho demasiado configurable donde pasas todas las propiedades, pero si no lo necesitas, puedes codificar las cosas.

fiddle EDITAR: Olvidé mencionar que el violín usa la sintaxis ES6 que creo que IE no admite actualmente.

algunos documentos

documentos de filtro

2
ste2425 12 may. 2016 a las 12:59