JavaScript:如何获取以特定字符串开头的对象的所有键和值?

20

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

我的对象如下所示:

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

但我只需要属性imageIdsimageIdsZh。然而,明天一个对象可能会包含imageIdsBlah,我也需要获取它。我可以从对象中删除前几个属性,但接下来的对象可能会包含其他属性,比如foo: 'bar'


有什么想法吗?使用普通的 foreach + if 怎么样? - zerkms
可能是如何列出JavaScript对象的属性的重复问题。 - ProllyGeek
也许你的对象应该分成两个对象。你可以在主对象上有一个子对象,或者你可以让主对象继承具有“imageIds”属性的对象,这样你就可以从原型链中简单地获取它。 - Blue Skies
注意:对象的属性/方法没有顺序。在浏览器中看到的任何顺序(测试时)都是“偶然”的,而不是按规范定义的!换句话说,它经常有效,但不能保证。 - GitaarLAB
5个回答

43

一些函数式编程的神奇之处:

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 对象。为此,我们使用初始值 {}(空对象),填充并从每个执行步骤返回。

更新:

根据@GitaarLAB的公正更新:

Object.keys 是 ES5 的函数,但返回对象自己的属性(因此不需要 obj.hasOwnProperty(key)


2
这里不需要使用 reduce,我认为。 - thefourtheye
@Blue Skies:这只是一种正常的责任分离。你正在将任务分成块。因此,好处是更可预测的设计。 - zerkms
2
好的,我接受这个解释。;-) - Blue Skies
2
@Blue Skies:这很好,因为我没有更好的选择;-) 这对我来说更自然。 - zerkms
1
我认为这很重要:Object.keys是ES5,但返回对象自己的属性(所以不需要 obj.hasOwnProperty(key))。请参见https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/keys。我想知道,这是否比其他解决方案(如我在这里回答的解决方案)更快(显着)? - GitaarLAB
显示剩余7条评论

2

根据对象的大小,这种方法可能不能很好地进行扩展,但它是有效的。

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

这是否准确回答了问题? - thefourtheye
我相信是的。有什么遗漏吗? - scrblnrd3
是的,我相信答案不完整。 - thefourtheye
如果 OP 执行此代码示例,是否可以解决他的问题? - thefourtheye
是的,因为它将获取所有以“imageIds”开头的属性。 - scrblnrd3

1

在使用for-in循环时,还需要与hasOwnProperty一起使用(大多数以前的答案都没有提到)。


原因是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工作。

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

希望这能帮到你!


1

沿用@zerkms的回答,我一直在为Javascript开发一个函数式编程库。使用该库中的工具,这可以变成一个(有点密集)的一行代码:

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中的少数几个。

您可以在JSFiddle上看到它的运行情况


0
 // 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;
}    

** 希望这对您有所帮助。如果您有任何进一步的问题,请随时联系我们。祝您好运。 **


你已经硬编码了键名,这正是提问者不想要的,也是他提出问题的整个目的。 - GitaarLAB

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接