JavaScript: Как я могу получить все ключи и значения объекта, которые начинаются с определенной строки?

Я пытаюсь получить все ключи и значения объекта, начинающегося с imageIds.

Мой объект выглядит следующим образом:

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

но мне нужны только свойства imageIds и imageIdsZh. Однако завтра объект может содержать imageIdsBlah, и мне тоже нужно будет его поднять. Я мог удалить первые несколько свойств из объекта, но затем следующий объект может содержать дополнительные свойства, такие как foo: 'bar'

Ответ 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/

Некоторые незначительные объяснения:

  • Мы используем функцию Array.prototype.filter() для фильтрации ключей, начинающихся с `imageIds2
  • Мы используем Array.prototype.reduce() для преобразования массива фильтрованных ключей в объект пар key-value. Для этого мы используем начальное значение {} (пустой объект), заполняем его и возвращаем с каждого этапа выполнения.

UPD

Яркое обновление от @GitaarLAB:

Object.keys является ES5, но возвращает собственные свойства объектов (поэтому нет необходимости в obj.hasOwnProperty(key))

Ответ 2

В зависимости от того, насколько велик объект, это может плохо масштабироваться, но оно будет работать

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

Ответ 3

Также нужно использовать 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 здесь.

Естественно, можно также нажать только значения: results.push(obj[key])
Я бы рекомендовал не возвращать объект ((results[key]=obj[key])), так как в этом случае проще работать с массивом.

Надеюсь, это поможет!

Ответ 4

По строкам ответа от @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.

Ответ 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;
}    

** Надеюсь, это было полезно. Если у вас возникнут дополнительные вопросы, не стесняйтесь обращаться к ним. Удачи. **