【问题标题】:JavaScript: How can I get all the keys and values of an object that begin with a specific string?JavaScript:如何获取以特定字符串开头的对象的所有键和值?
【发布时间】:2013-12-10 03:06:55
【问题描述】:

我正在尝试获取以imageIds 开头的对象的所有键和值。

我的对象如下所示:

{
    title: 'fsdfsd',
    titleZh: 'fsdfsd',
    body: 'fsdf',
    bodyZh: 'sdfsdf',
    imageIds: '/uploads/tmp/image-3.png',
    imageIdsZh: '' 
}

但我只需要属性imageIdsimageIdsZh。但是明天,一个对象可能包含imageIdsBlah,我也需要把它捡起来。我可以从对象中删除前几个属性,但是下一个对象可能包含其他属性,例如 foo: 'bar'

【问题讨论】:

  • 有什么想法吗?普通的旧 foreach + if 怎么样?
  • 也许你的对象应该被分成两个对象。你可以在主对象上有一个子对象,或者你可以让主对象继承自具有imageIds 属性的对象,这样你就可以简单地从原型链中获取它。
  • 注意:对象的属性/方法中没有no顺序。浏览器中感知到的任何顺序(在测试时)都是“意外”并且不是符合规范!换句话说,它通常有效,但不能保证。

标签: javascript


【解决方案1】:

一些功能性的风格很棒:

var data = {
    title: 'fsdfsd',
    titleZh: 'fsdfsd',
    body: 'fsdf',
    bodyZh: 'sdfsdf',
    imageIds: '/uploads/tmp/image-3.png',
    imageIdsZh: '' 
};

var z = Object.keys(data).filter(function(k) {
    return k.indexOf('imageIds') == 0;
}).reduce(function(newData, k) {
    newData[k] = data[k];
    return newData;
}, {});

console.log(z);

演示:http://jsfiddle.net/ngX4m/

一些小解释:

  1. 我们使用Array.prototype.filter()函数过滤掉以`imageIds2开头的键
  2. 我们使用Array.prototype.reduce() 将过滤后的键数组转换为key-value 对的对象。为此,我们使用{}(一个空对象)的初始值,填充它并从每个执行步骤返回。

UPD

来自@GitaarLAB的公平更新:

Object.keys 是 ES5,但返回一个对象自己的属性(所以不需要obj.hasOwnProperty(key)

【讨论】:

  • @scrblnrd3:有什么特别的问题吗?
  • 我认为这里不需要reduce
  • 好的,我会接受那个解释。 ;-)
  • @Blue Skies:这很好,因为我没有更好的 ;-) 这对我来说更自然
  • 我认为补充一点很重要:Object.keys 是 ES5,但返回一个对象自己的属性(所以不需要 obj.hasOwnProperty(key))。请参阅developer.mozilla.org/en/JavaScript/Reference/Global_Objects/… 我想知道,这(显着)是否比其他解决方案(如我在这里回答的解决方案)更快?
【解决方案2】:

根据对象的大小,这可能无法很好地扩展,但它会起作用

for(key in obj){
   if(obj.hasOwnProperty(key)){
      if(key.indexOf("imageIds")===0){
        //do something
      }
   }
}

【讨论】:

  • 这是否准确地回答了这个问题?
  • 我相信是的。有什么遗漏吗?
  • 是的。我相信答案并不完整。
  • 如果OP执行代码示例,会解决他的问题吗?
  • 是的,因为它将获取所有以“imageIds”开头的属性
【解决方案3】:

根据 @zerkms 的回答,我一直在为 Javascript 编写 functional programming library。使用该库中的工具,这变成了(有点密集的)单线:

var data = {
    title: 'fsdfsd',
    titleZh: 'fsdfsd',
    body: 'fsdf',
    bodyZh: 'sdfsdf',
    imageIds: '/uploads/tmp/image-3.png',
    imageIdsZh: '' 
};

var x = pick(filter(compose(eq("imageIds"), substring(0,8)), keys(data)), data);
console.log(x);

这段代码不一定比 @zerkms 发布的代码更好,但它确实展示了一些功能抽象的强大功能,而不仅仅是 Array.prototype 中内置的少数几个功能抽象。 p>

您可以see it in action on JSFiddle

【讨论】:

    【解决方案4】:

    还需要将hasOwnProperty 与for-in 循环结合使用(在大多数当前之前的答案中都没有提到)。
    原因是 for-in 循环还将遍历对象将从原型链继承的方法/属性(如果有人或某些库添加了自定义内容)。

    所以你正在寻找像这样简单可靠的东西:

    function fetch(obj, str){
        var key, results = [];
        for(key in obj) obj.hasOwnProperty(key) 
                     && key.indexOf(str) === 0 
                     && results.push([ key, obj[key] ]);
        return results;
    }
    

    注意:您也可以将此函数命名为“getAllKeysAndValuesStartingWith”(如果您为军队工作,也可以命名为 gakavsw,哈哈)。

    用法:

    fetch(object, string) 返回一个带有找到结果的简单(循环)数组,
    所以var my_results = fetch(testObj, 'imageId'); 会给出以下输出:

    [ //array of arrays
      ['imageIds', '/uploads/tmp/image-3.png']
    , ['imageIdsZh', '']                               /* 
    , [key, value]           and more if it finds them */
    ]
    

    工作jsfiddle here

    当然也可以只推送值:results.push(obj[key])
    我建议不要返回一个对象 ((results[key]=obj[key])),因为在这种情况下数组更容易使用。

    希望这会有所帮助!

    【讨论】:

      【解决方案5】:
       // json to be searched
      var data = {
          title: 'fsdfsd',
          titleZh: 'fsdfsd',
          body: 'fsdf',
          bodyZh: 'sdfsdf',
          imageIds: '/uploads/tmp/image-3.png',
          imageIdsZh: '' 
      };
      
      
      // takes the json 'data' as its 1st parameter
      // and the desired 'property' to be searched as the 2nd parameter
      // for loop iterates through the entire json
      // if the property parameter matches a 'key' name in json e.g. 'imageIds'
      // then the value for that property is returned
      function fetchProperty (data, property) {
          for(var key in data) {
              if(key === property) {
                  return data[key];
              }   
          }
      }
      
      
      // if you wanted to return a bunch of data according to a particular key - value pair
      // you could do something like this...
      // assume 'array' contains a bunch of jsons 
      // newData will hold jsons containing your newly fetched data points
      function fetchNewData() {
         var newData = [];
         for(var i = 0; i < array.length; i++) {
      
            var value1 = fetchProperty(array[i], 'imageIds');
            var value2 = fetchProperty(array[i], 'imageIdsZh');
            var value3 = fetchProperty(array[i], 'imageIdsBlah');
      
            var tempJSON = {};
            tempJSON.imageIds = value1;
            tempJSON.imageIdsZh = value2;
            tempJSON.imageIdsBlah = value3;
      
            newData.push(tempJSON);
         }
         return newData;
      }    
      

      ** 我希望这会有所帮助。如果您还有其他问题,请随时与我们联系。祝你好运。 **

      【讨论】:

      • 你已经硬编码了提问者不想要的键名,这是他问题的全部目的。
      猜你喜欢
      • 1970-01-01
      • 2016-05-18
      • 2015-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-29
      • 1970-01-01
      相关资源
      最近更新 更多