Сопоставить массив и вернуть новый на основе ключей объекта

1

Это исходный массив:

let list = [
    {
        city: "new york", 
        current_time: "123", 
        time1: "456", 
        time2: "789",
    },
    {
        city: "london",
        current_time: "123",
        time1: "456",
        time2: "789",
    },
    {
        city: "tokyo",
        current_time: "123",
        time1: "456",
        time2: "789",
    }
]

Я пытаюсь создать массив массивов, где каждый внутренний массив содержит объекты с городом и временем. Но организованная CURRENT_TIME, time1 или time2.

Ожидаемый результат:

result = [
    [{
        city: "new york",
        time: "123"
    }, {
        city: "london",
        time: "123"
    }, {
        city: "tokyo",
        time: "123"
    }],
    [{
        city: "new york",
        time: "456"
    }, {
        city: "london",
        time: "456"
    }, {
        city: "tokyo",
        time: "456"
    }], [{
        city: "new york",
        time: "789"
    }, {
        city: "london",
        time: "789"
    }, {
        city: "tokyo",
        time: "789"
    }]
]

Я попытался использовать функцию карты, но я могу создать массив только с current_time, мне, вероятно, придется перебирать ключи, но я смущен, если мне нужно использовать forEach или лучший способ повторения.

result = list.map((element, index) => {
    if(element.current_time) {
        return { city: element.city, time: element.current_time };
});
  • 0
    Вы возвращаете объект в функции карты, а не массив с 3 объектами для разных времен, и даже этого недостаточно, поскольку город не является общим. так что используйте список [id] .city
Теги:
arrays

5 ответов

2
Лучший ответ

Вы можете использовать массив для ключей и отобразить результат сопоставленных значений данного массива.

var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456", time2: "789" }],
    keys = ["current_time", "time1", "time2"],
    result = keys.map(k => list.map(o => ({ city: o.city, time: o[k] })));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Другим подходом может быть итерация данных и их уменьшение путем итерации ключей для поиска объектов с индексом ключей.

var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", current_time: "123", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456", time2: "789" }],
    keys = ["current_time", "time1", "time2"],
    result = list.reduce((r, o) => {
        keys.forEach((k, i) => (r[i] = r[i] || []).push({ city: o.city, time: o[k] }));
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Немного измененная версия для данных с некоторыми отсутствующими ключами.

var list = [{ city: "new york", current_time: "123", time1: "456", time2: "789" }, { city: "london", time1: "456", time2: "789" }, { city: "tokyo", current_time: "123", time1: "456" }],
    keys = ["current_time", "time1", "time2"],
    result = list.reduce((r, o) => {
        keys.forEach((k, i) => k in o && (r[i] = r[i] || []).push({ city: o.city, time: o[k] }));
        return r;
    }, []);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
  • 0
    Большое спасибо! Я просто забыл одну деталь. Иногда в списке не все ключи. Например, объект только с current_time и time1. Должно ли это получить это динамически на карте?
  • 0
    Вы можете добавить проверку и нажать, если ключ существует, как в третьей части.
Показать ещё 1 комментарий
0

Я принял подход к определению нового пустого массива и сброса на пустой для каждого элемента. этот массив заселен прохождением через цикл каждого свойства элемента, который не является городом, и нажимает новый объект с городом и временем собственности.

Надеюсь, это было бы полезно.

var list = [
{ city: "new york", 
  current_time: "123", 
  time1: "456", 
  time2: "789",
},
 { city: "london",
   current_time: "123",
   time1: "456",
   time2: "789",
},
{ city: "tokyo",
  current_time: "123",
  time1: "456",
  time2: "789",
}];
var arr = []
var result = list.map((ele) => {
   arr = []
   for(var prop in ele){
      if(prop != 'city') arr.push({city: ele['city'], time: ele[prop]})
     }
    return arr
  })
  
console.log('result =', result)
0

var list = [{
        city: "new york",
        current_time: "123",
        time1: "456",
        time2: "789",
    },
    {
        city: "london",
        current_time: "123",
        time1: "456",
        time2: "789",
    },
    {
        city: "tokyo",
        current_time: "123",
        time1: "456",
        time2: "789",
    }
];
let timeKeys = Object.keys(list[0]);
timeKeys.shift();
let finalArray = timeKeys.map(val => list.map(nestedVal => ({
    city: nestedVal.city,
    time: nestedVal[val]
})));

console.log(finalArray);
0

Функция map создает новый массив с той же длины, что и оригинал, так, что вам нужно сделать, это зацикливание этот массив и сгруппировать эти значения.

Альтернативой является использование функции reduce

let list = [{ city: "new york",   current_time: "123",   time1: "456",   time2: "789"}, { city: "london",   current_time: "123",   time1: "456",   time2: "789"},{ city: "tokyo",  current_time: "123",  time1: "456",  time2: "789"}],
    keys = ['current_time', 'time1', 'time2'],
    result = Object.values(list.reduce((a, c) => {
      keys.forEach(k => (a[c[k]] || (a[c[k]] = [])).push({ city: c.city, time: c[k] }));
      return a;
    }, {}));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
0

Я надеюсь, это поможет вам

let list = [{
  city: "new york",
  current_time: "123",
  time1: "456",
  time2: "789"
}, {
  city: "london",
  current_time: "123",
  time1: "456",
  time2: "789"
}, {
  city: "tokyo",
  current_time: "123",
  time1: "456",
  time2: "789"
}, {
  city: "tokyo",
  current_time: "1223",
  time1: "456",
  time2: "789"
}, {
  city: "tokyo",
  current_time: "1223",
  time1: "456",
  time2: "789"
}],
obj = {};

list.forEach(function(itm) {
  if (!obj.hasOwnProperty(itm.current_time)) {
    obj[itm.current_time] = [];
  }
  obj[itm.current_time].push(itm);
});

let result = [];
var keys = Object.keys(obj);
for (var i = 0; i < keys.length; i++) {
  result.push(obj[keys[i]]);
}

console.log(result);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню