【问题标题】:Lodash to find if object property exists in arrayLodash查找数组中是否存在对象属性
【发布时间】:2017-03-01 11:39:31
【问题描述】:

我有一个这样的对象数组:

[ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

我想插入另一个元素,也命名为apple,但是,因为我不想在其中重复,我如何使用 lodash 来查看数组中是否已经存在同名的对象?

【问题讨论】:

  • ARRAY.find(function(el){ return el.name === 'apple'; }) 如果undefined,则数组中没有名称为"apple"的元素
  • @reectrix _.has(object, path)

标签: javascript arrays reactjs lodash


【解决方案1】:

你可以像这样使用 Lodash _.find()

var data = [ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

if(!_.find(data, {name: 'apple'})) {
  data.push({name: 'apple2'});
}
console.log(data)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

参考文档:https://lodash.com/docs/4.17.14#find

【讨论】:

  • _.find() 文档的链接:https://lodash.com/docs/#find
  • 这不是检查属性是否存在,而是假设属性存在,并检查是否具有正确的值。错误的答案。虽然是一个令人困惑的问题,但男人会问一件事,然后解释另一件事
【解决方案2】:

这是表格

_.has(object, path)

例子:

const countries = { country: { name: 'Venezuela' } }
const isExist = _.has(countries, 'country.name')
// isExist = true

欲了解更多信息Document Lodash

【讨论】:

  • _.has 说明该路径是否存在,而不是关于值。
【解决方案3】:

你可以使用Array.prototype.find()或者lodash的_.find()

const addItem = (arr, item) => {
  if(!arr.find((x) => x.name === item.name)) { // you can also change `name` to `id`
    arr.push(item);
  }
};

const arr = [ 
  {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
];

addItem(arr, { "name": "apple", "id": "apple_0" });

addItem(arr, { "name": "pear", "id": "pear_3" });

console.log(arr);

还有一个更短但可读性较差的版本:

    const addItem = (arr, item) => arr.find((x) => x.name === item.name) || arr.push(item); // you can also change `name` to `id`

    const arr = [ 
      {"name": "apple", "id": "apple_0"}, 
      {"name": "dog",   "id": "dog_1"}, 
      {"name": "cat", "id": "cat_2"}
    ];

    addItem(arr, { "name": "apple", "id": "apple_0" });

    addItem(arr, { "name": "pear", "id": "pear_3" });

    console.log(arr);

【讨论】:

  • IMO,最好用`=== undefined`来测试它
  • 为什么 - !undefined === true?
  • 可读性是一个很好的动机,但确实是个人意见。我将添加一个更短且可读性更低的选项:)
  • 如果它是[0,1,2] 的数组并且您正在查找0,在这种情况下为!0 === true;,在这种特定情况下,您的方法很好:)
  • 确实你是对的,但在处理对象时不是这样。
【解决方案4】:

这是另一个使用 lodash 的例子

var a = [ {"name": "apple", "id": "apple_0"}, 
  {"name": "dog",   "id": "dog_1"}, 
  {"name": "cat", "id": "cat_2"}
]

var b = _.find(a, ['name', "apple2"]);

if(_.isObject(b)){
  console.log('exists')
}else{
    console.log('insert new')
}

https://jsfiddle.net/jorge182/s4og07jg/

【讨论】:

    【解决方案5】:

    这对我有用(在测试了不同的解决方案之后):

      addItem(items, item) {
        let foundObject = _.find(items, function(e) {
          return e.value === item.value;
        });
    
        if(!foundObject) {
          items.push(item);
        }
        return items;
      }
    

    【讨论】:

      【解决方案6】:

      如果您只想在数组中插入一个值,则可以选择使用_.find。但是,如果您有兴趣插入一个或多个,我建议您改用_.unionBy

      var currentArr = [{
          "name": "apple",
          "id": "apple_0"
        }, {
          "name": "dog",
          "id": "dog_1"
        }, {
          "name": "cat",
          "id": "cat_2"
        }],
        arrayOneValue = [{
          "name": "apple",
          "id": "apple_0"
        }],
        arrayTwoValues = arrayOneValue.concat({
          "name": "lemon",
          "id": "lemon_0"
        })
      
      console.log(_.unionBy(currentArr, arrayOneValue, 'name'));
      console.log(_.unionBy(currentArr, arrayTwoValues, 'name'));
      // It also allow you to perform the union using more than one property
      console.log(_.unionBy(currentArr, arrayTwoValues, 'name', 'id'));
      <script src="https://cdn.jsdelivr.net/lodash/4.16.4/lodash.min.js"></script>

      【讨论】:

        【解决方案7】:

        以下是使用lodash 4.17.5 实现此目的的三种方法:

        假设您想将对象entry 添加到对象数组numbers 中,前提是entry 尚不存在。

        let numbers = [
            { to: 1, from: 2 },
            { to: 3, from: 4 },
            { to: 5, from: 6 },
            { to: 7, from: 8 },
            { to: 1, from: 2 } // intentionally added duplicate
        ];
        
        let entry = { to: 1, from: 2 };
        
        /* 
         * 1. This will return the *index of the first* element that matches:
         */
        _.findIndex(numbers, (o) => { return _.isMatch(o, entry) });
        // output: 0
        
        
        /* 
         * 2. This will return the entry that matches. Even if the entry exists
         *    multiple time, it is only returned once.
         */
        _.find(numbers, (o) => { return _.isMatch(o, entry) });
        // output: {to: 1, from: 2}
        
        
        /* 
         * 3. This will return an array of objects containing all the matches.
         *    If an entry exists multiple times, if is returned multiple times.
         */
        _.filter(numbers, _.matches(entry));
        // output: [{to: 1, from: 2}, {to: 1, from: 2}]
        
        
        /* 
         * 4. This will return `true` if the entry exists, false otherwise.
         */
        _.some(numbers, entry);
        // output: true
        

        如果你想返回一个Boolean(即假设你没有使用_.some()),在第一种情况下,你可以简单地检查返回的索引值:

        _.findIndex(numbers, (o) => { return _.isMatch(o, entry) }) > -1;
        // output: true
        

        Lodash documentation 是示例和实验的重要来源。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-12-11
          • 2020-11-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-02-27
          • 1970-01-01
          相关资源
          最近更新 更多