使用 Lodash 通过 It's key 获取值,而某些键不存在

Using Lodash to get value by It's key while some keys don't exist

如何在通过数组进行映射以获取和分配相关值时使用 Lodash?

这就是我未过滤的数组的样子,我想将 ID 和名称[x].text 提取到一个数组中。但是正如您所看到的,有些对象中没有法语文本,在这种情况下,我想改用英文文本。

const response = {
    "data": {
      "Animals": [
        {
          "id": "1",
          "name": [
            {
              "language": "en-US",
              "text": "Horse"
            }
          ]
        },
        {
          "id": "2",
          "name": [
            {
              "language": "en-US",
              "text": "Pig"
            }
          ]
        },
       {
          "id": "3",
          "name": [
            {
              "language": "en-US",
              "text": "Cat"
            },
            {
              "language": "fr-CA",
              "text": "Un Chat"
            }
          ]
        },
        {
          "id": "4",
          "name": [
            {
              "language": "en-US",
              "text": "Dog"
            },
            {
              "language": "fr-CA",
              "text": "Un Chien"
            }
          ]
        }
      ]
    }
  }


console.log(response.data.Animals.map(animal => animal.name[0].text)); // If I do this I get all the English text, but If I map the same with index of the French, I get undefined error and It crashed my application.

这更符合 table 因为它 returns 法文和英文文本,但有两个我想做的改进,

  1. 从它的键(“en-US”和“fr-CA”)中获取值,以便我确定我有正确的值。

  2. 我正在映射以填充一个 table,所以我不需要一个带有值的新数组,因为我不想丢失父数组的索引,如果是文本不可用它应该去寻找英文文本。

  3. 这是一个额外的问题,但它会帮助我更好地学习使用 Lodash,如果我想设置值(En 或 Fr),我该怎么做?

     arr.map((obj) => {
     const id = obj.id;
     const englishtext = _.get(obj, 'name[0].text', 'N/A');
     const frenchtext = _.get(obj, 'name[1].text', englishtext);
     return { id, englishtext, frenchtext };
    

    }

更新: 很抱歉我的问题不清楚,老实说我也有点困惑。所以这是我正在寻找的预期输出。所以当我映射给定的变量响应时,我想要另一个看起来像这样的数组,

预期输出:

[
{
id: 1,
engname: Horse,
frenchname: Horse (because french is not available),
},
.
.
.
{
id:3,
engname:Cat,
frenchname: Un Chat, (because the French array is there this time)
}
.
.
.
and so on.. 
] 

我会 post 一个非 Lodash 版本的解决方案,因为我认为在这种情况下不需要 Lodash。但是我知道你问的是 Lodash 解决方案,所以如果你必须使用 Lodash,请忽略这个。

如果我对你的问题的理解正确,你想用来提取值的规则集如下:

  1. 如果有法语文本,请使用它,而不管英语文本是否存在。此外,法语文本始终位于数组中的英语文本之后(法语文本的索引始终为 -1)。

  2. 如果没有法语文本,请使用英文文本(保证所有项目都有英文文本)。

在那种情况下,我认为您可以使用 Array.prototype.pop()Array.prototype.at() 来实现您想要的效果。

Array.prototype.pop()解决方案

response.data.Animals.map(animal => animal.name.pop().text)

优点:

  • 在所有现代浏览器中广泛可用。

缺点:

  • 这会改变原始数据并改变原始数组的长度。

Array.prototype.at()解决方案

response.data.Animals.map(animal => animal.name.at(-1).text)

优点:

  • 这个操作是不可变的,所以原始数据是完整的。

缺点:

  • 有些浏览器可能不支持这个。

如果您对非 Lodash 解决方案持开放态度,我想您可以使用其中之一。

更新

感谢@WildThing 更新问题。我想你可以用它来实现你想要的映射:

response.data.Animals.map(animal => {
  engName = animal.name.find(name => name.language === "en-US");
  frenchNameIfExists = animal.name.find(name => name.language === "fr-CA");

  return {
    id: animal.id,
    engname: engName.text,
    frenchname: (frenchNameIfExists || engName).text,
  }
})

可能不需要lodash:

const toMyArray = (arr, frenchnameCode = "fr-CA", engnameCode = "en-US") => {
  return arr.map(({ id, name }) => {
    const engname = name
      .find(({ language }) => language === engnameCode)
      .text;
    const frenchname =  name
      .find(({ language }) => language === frenchnameCode)
      ?.text;
      
    return { id, engname, frenchname: frenchname ?? engname }
  });
};

console.log(toMyArray(response.data.Animals));

// [
//   {id: '1', engname: 'Horse', frenchname: 'Horse'},
//   {id: '2', engname: 'Pig', frenchname: 'Pig'},
//   {id: '3', engname: 'Cat', frenchname: 'Un Chat'},
//   {id: '4', engname: 'Dog', frenchname: 'Un Chien'},
// ]