使用 lodash 过滤深层嵌套对象数组无法正常工作

filtering deep nested objects array using lodash not working correctly

我的产品结构如下图:

   product = {  
  "name":"MyXam",
  "layers":[  
    {  
      "countries":[  
        {  
          "countryId":"1",
          "countryName":"ABC"
        },
        {  
          "countryId":"2",
          "countryName":"XYZ"
        },
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    },
    {  
      "countries":[  
        {  
          "countryId":"5",
          "countryName":"LMN"
        },
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    }
  ]
}

和选定的国家:

selCountries =    [  
  {  
    "countryId":"1"
  },
  {  
    "countryId":"3"
  }
]

现在我想过滤 product,使其只包含 countries selCountries.

中的内容

最终产品应该是:

{  
  "name":"MyXam",
  "layers":[  
    {  
      "countries":[  
        {  
          "countryId":"1",
          "countryName":"ABC"
        },
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    },
    {  
      "countries":[  
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    }
  ]
}

我使用 lodash 尝试了以下方法,但没有用:

_.filter(product.layers, _.flow(
      _.property('countries'),
      _.partialRight(_.some, selCountries)
  ));

因为 product 在我的应用程序中动态出现。在某些情况下,某些 layers 可能没有 countries。所以解决方案也应该处理这种情况,并且不应该因未定义的错误而中断。

任何人都可以帮助我,我哪里出错了?

你不应该为此需要 lodash。只是 filter 基于 ID。如果对于所有图层,map/forEach 在图层上过滤国家。

const product = {  
  "name":"MyXam",
  "layers":[  
    {  
      "countries":[  
        {  
          "countryId":"1",
          "countryName":"ABC"
        },
        {  
          "countryId":"2",
          "countryName":"XYZ"
        },
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    }
  ]
}

const selCountries = [  
  {  
    "countryId":"1"
  },
  {  
    "countryId":"3"
  }
];

const indices = selCountries.map(e => e.countryId); // Just IDs plz.
product.layers.forEach(layer => {
   if (layer.countries == null)
       return;

   layer.countries = layer.countries.filter(e => 
       indices.some(i => i == e.countryId)
   );
});
console.log(product);

您可以使用所选国家/地区的 ID 创建一个临时数组,然后根据它过滤国家/地区。请注意,它修改了原始对象 in-place.

let product = {
  "name": "MyXam",
  "layers": [{
    "countries": [{
        "countryId": "1",
        "countryName": "ABC"
      },
      {
        "countryId": "2",
        "countryName": "XYZ"
      },
      {
        "countryId": "3",
        "countryName": "PQR"
      }
    ]
  }]
};

let selCountries = [{
    "countryId": "1"
  },
  {
    "countryId": "3"
  }
];

// Extract the IDs
let selCountryIds = _.map(selCountries, 'countryId');

// Filter the countries based on IDs
product.layers[0].countries = _.filter(product.layers[0].countries, country => {
  return _.includes(selCountryIds, country.countryId);
});

console.log(product);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.5/lodash.min.js"></script>

您可以使用 Array.mapArray.filter 来遍历数组并根据 [=15= 过滤 product 而不是使用 lodash ]

var product = {  
  "name":"MyXam",
  "layers":[  
    {  
      "countries":[  
        {  
          "countryId":"1",
          "countryName":"ABC"
        },
        {  
          "countryId":"2",
          "countryName":"XYZ"
        },
        {  
          "countryId":"3",
          "countryName":"PQR"
        }
      ]
    }
  ]
}


var selCountries =    [  
  {  
    "countryId":"1"
  },
  {  
    "countryId":"3"
  }
];

product.layers = product.layers.map(function (layer) {
  return layer.countries.filter(function (country) {
    return selCountries.some(function(selCountry) {
      return selCountry.countryId === country.countryId;
    });
  });
});

console.log(product);

我的回答与 31piy 的类似,因为我先从 selCountries 中提取出 id,然后用过滤后的结果重建对象。它还根据您最近的评论检查图层数组中是否有国家/地区。

product = {"name":"MyXam","layers":[{"countries":[{"countryId":"1","countryName":"ABC"},{"countryId":"2","countryName":"XYZ"},{"countryId":"3","countryName":"PQR"}]},{"countries":[{"countryId":"5","countryName":"LMN"},{"countryId":"3","countryName":"PQR"}]}]}
const selCountries=[{"countryId":"1"},{"countryId":"3"}];

if (product.layers.length) {
  const selCountriesArr = selCountries.map(el => el.countryId);
  const newLayers = product.layers.map(obj => {
    const countries = obj.countries.filter(el => selCountriesArr.includes(el.countryId));
    return { countries };
  });
  const filteredProduct = { ...product, layers: newLayers };
  console.log(filteredProduct);
}