从键以特定模式结尾的对象中获取所有值

Get all values from an Object who's key ends with a particular pattern

本文关键字:对象 获取 结尾 模式      更新时间:2023-09-26

我正在尝试从对象中检索所有键值,其中键名以(例如_abc(结尾。

我的尝试

obj = {p1_abc: 1, p2_abc: 2, p3_def: 3, p4_abc: 4, p5_def: 5}
required_keys = jQuery.map(Object.keys(obj), function(val, i){
  if(val.indexOf("_abc") != -1)
    return val;
});
//required_keys = ['p1_abc', 'p2_abc', 'p4_abc']
required_values = jQuery.map(required_keys, function(v, i){
  return(obj[v]);
});
//required_values = [1, 2, 4]

在这里,required_values包含我需要的值,但我觉得整个代码有点丑陋。有没有一种干净的方法来实现这一目标?

有几分钟的空闲时间,这似乎是一个很好的问题来介绍iterators

下面是一个用 ES5 编写的示例,但它也可以在加载填充程序的 ES3 中工作。

function makeEntriesIterator(object) {
  var keys = Object.keys(object);
  var nextKey = 0;
  return {
    next: function next() {
      if (nextKey < keys.length) {
        var key = keys[nextKey];
        var iterator = {
          value: [key, object[key]],
          done: false
        };
        nextKey += 1;
        return iterator;
      }
      return {
        value: undefined,
        done: true
      };
    }
  };
}
var obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
};
var iterator = makeEntriesIterator(obj);
var next = iterator.next();
var matches = [];
while (!next.done) {
  if (next.value[0].slice(-4) === '_abc') {
    matches.push(next.value);
  }
  next = iterator.next();
}
document.getElementById('out').textContent = JSON.stringify(matches, null, 2);
console.log(matches);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<pre id="out"></pre>

在 ES6 中,可以使用 for..of 代替 while 数组有迭代器valuesentrieskeys,默认Symbol.iteratorvalues

'use strict';
const obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
};
const matches = [];
for (let key of Object.keys(obj)) {
  if (key.endsWith('_abc')) {
    matches.push([key, obj[key]]);
  }
}
document.getElementById('out').textContent = JSON.stringify(matches, null, 2);
console.log(matches);
<script src="https://cdnjs.cloudflare.com/ajax/libs/es5-shim/4.4.1/es5-shim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/es6-shim/0.34.0/es6-shim.js"></script>
<pre id="out"></pre>

ES7 将为对象引入迭代器,例如entries,然后事情变得更加干净,因为您无需使用 Object.keys .但这现在还不能证明。

'use strict';
const obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
};
const matches = [];
for (let [key, value] of obj) {
  if (key.endsWith('_abc')) {
    matches.push([key, value]);
  }
}
首先使用

Object.keys() 从对象中获取所有属性,然后用 Array.prototype.filter() 过滤数组以获取所需的属性,最后使用对象的括号运算符从对象中收集所有值,并返回它Array.prototype.map()以获得一个漂亮的数组。

var obj = { p1_abc: 1, p2_abc: 2, p3_def: 3, p4_abc: 4, p5_def: 5, _abcp6: 6 },
    required_values = Object.keys(obj).filter(function (a) {
        return /_abc$/.test(a);
    }).map(function (a) {
        return obj[a];
    });
document.write('<pre>' + JSON.stringify(required_values, 0, 4) + '</pre>');

您可以在一个.map()中执行此操作

obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
}
required_keys = jQuery.map(Object.keys(obj), function(val, i) {
  if (val.indexOf("_abc") != -1) {
    return obj[val];
  }
});
document.write(required_keys);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

或者如果你想要键/值,你可以这样做

obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
}
required_keys = jQuery.map(Object.keys(obj), function(val, i) {
  if (val.indexOf("_abc") != -1) {
    return {[val]:obj[val]};
  }
});
document.write(JSON.stringify(required_keys));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

您应该使用reduce同时过滤和减少项目

var obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
}
var regex = /_abc$/;
var required_values = Object.keys(obj).reduce(function(sum, key) {
  if (regex.test(key)) {
    sum.push(obj[key]);
  }
  return sum;
}, []);
console.log(required_values);
<script src="https://getfirebug.com/firebug-lite-debug.js"></script>

尝试使用 for..in 循环 ,RegExp.prototype.test() RegExp /_abc$/ 来匹配以 "_abc" 结尾的对象的属性

var obj = {
  p1_abc: 1,
  p2_abc: 2,
  p3_def: 3,
  p4_abc: 4,
  p5_def: 5
};
for (prop in obj) {
  if (/_abc$/.test(prop))
    console.log(obj[prop]) // do stuff with `prop` , `obj[prop]`
}

当你标记Jquery时,你可以使用$.each()

var obj = {p1_abc: 1, p2_abc: 2, p3_def: 3, p4_abc: 4, p5_def: 5}
$.each(obj , function(k , v){
  if (k.indexOf("_abc") != -1){
        alert(v)
  };
})

工作演示

返回数组

var obj = {p1_abc: 1, p2_abc: 2, p3_def: 3, p4_abc: 4, p5_def: 5}
var requireKeys = [];
$.each(obj , function(k , v){
  if (k.indexOf("_abc") != -1){
      requireKeys.push(v);
  };
})
alert(requireKeys);

工作演示

如果你有一个大型数据集,我更喜欢"高性能"而不是"干净"。这不是"最干净"的代码,但它的性能将高于任何其他解决方案(到目前为止(。

function getValues (obj) {
  var values = []
  for(var key in obj){
    if (key.substr(key.length - 4) === '_abc') {
      values.push(obj[key])
    }
  }
  return values
}

这是findKey函数实现。

它返回第一个元素谓词的键,返回 truthy 而不是元素本身。

/**
 * @param {Object} collection The collection to inspect.
 * @param {Function} predicate The function.
 * @returns {*} Returns the key, else `undefined`. 
 */
var findKey = function(object, predicate) {
  let result;
  if (object == null) {
    return result;
  }
  Object.keys(object).some(function(key) {
    const value = object[key]
    if (predicate(value, key, object)) {
      result = key;
      return true;
    }
  })
  return result;
}

用法

//Example usage
var collections = {
  brand_category_3320: 1133,
  brand_category_3321: 2245
};
var r = findKey(collections, function(o, key, context) {
  if (key.indexOf(3320) > -1) {
    return true;
  }
  return false;
});
console.log('The r is =', r);

    obj = {
      p1_abc: 1,
      p2_abc: 2,
      p3_def: 3,
      p4_abc: 4,
      p5_def: 5
    }
    required_data = Object.keys(obj).map(function(val, i) {
      if (val.indexOf("_abc") != -1)
        return {
          [val]: obj[val]
        };
    });
    console.log(required_data);

将生成一个新的重新引用对象的数组,此外,您还可以删除 jQuery。