将对象值映射到键-Javascript

时间:2018-10-30 19:46:51

标签: javascript arrays lodash javascript-objects

我有一个来自API调用的数组。

var response = {
  "data": {
    "data": [{
      "1": "Arun",
      "index": "name"
    }, {
      "1": 70.78,
      "index": "score"
    }]
  }
}

我连接到许多其他API,它们向我返回了类似的响应,但是密钥发生了变化。有时候可能是

var response = {
  "data": {
    "data": [{
      "values": "Harry",
      "index": "name"
    }, {
      "values": 45,
      "index": "score"
    }]
  }
}

var response = {
  "data": {
    "data": [{
      "4": "Richard",
      "index": "name"
    }, {
      "4": 98,
      "index": "score"
    }]
  }
}

我想要一个这样的数组。

[
  {
    name: 'Arun',
    score: 70.78
  }
]

这就是我所做的。

var response = {
  "data": {
    "data": [{
      "1": "Arun",
      "index": "name"
    }, {
      "1": 70.78,
      "index": "score"
    }]
  }
}

const result = [];

const mappedData = _.map(response.data.data, (item) => {
  return {
    [item.index]: item[1]
  };
});

const resultObject = _.reduce(mappedData, (result, currentObject) => {
  for (const key in currentObject) {
    if (currentObject.hasOwnProperty(key)) {
      result[key] = currentObject[key];
    }
  }
  return result;
}, {});

result.push(resultObject)


console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

因此,不是在map函数中对“ 1”或“值”进行硬编码,有没有更通用的方法来获取键并获得相同的结果?

谢谢。

4 个答案:

答案 0 :(得分:3)

使用reduce而不是map,因此您要更新同一对象,而不是创建数组。

由于包含值的属性可能会有所不同,因此我使用循环来查找未命名为index的第一个属性,并使用其值。

var response = {
  "data": {
    "data": [{
      "1": "Arun",
      "index": "name"
    }, {
      "1": 70.78,
      "index": "score"
    }]
  }
}

const mappedData = response.data.data.reduce((acc, item) => {
  var value;
  // find the property that isn't named "item"
  for (var i in item) {
    if (i != "index") {
      value = item[i];
      break;
    }
  }
  acc[item.index] = value;
  return acc;
}, {});

console.log(mappedData)

不需要lodash,内置的reduce功能很好(但是_.reduce的工作原理类似)。

答案 1 :(得分:1)

由于您只关心该对象的值,并且它只有两个键,因此您可以使用reducefromPairs在lodash中轻松完成此操作:

var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } }

const rv = (o) => _.reverse(_.values(o))
const r = _.reduce(response.data.data, (a,c) => _.fromPairs([rv(a), rv(c)]))

console.log(r)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

转换为ES6的相同内容是:

var response = { "data": { "data": [{ "1": "Arun", "index": "name" }, { "1": 70.78, "index": "score" }] } }

const rv = (o) => Object.values(o).reverse()  // reverse values
const fp = (arr) => arr.reduce((r, [k,v]) => (r[k] = v, r), {}) // from pairs
const result = response.data.data.reduce((a,c) => fp([rv(a), rv(c)]))

console.log(result)

这里的主要思想是首先以数组形式获取对象值,将它们反转以使keyvalue处于正确的顺序,然后通过reduce {1}}创建最终对象。

这种方法的主要优点是我们从不处理对象键,而只关注您真正关心的值。这样,键可以是任何值,并且仍然没有关系。

答案 2 :(得分:0)

您可以尝试删除键对value,并使用结果对象的第一个const mappedData = _.map(response.data.data, (item) => { var tempObj = Object.assign({}, item) var index = tempObj.index; delete tempObj.index; var otherData = Object.values(tempObj)[0]; return { [index]: otherData }; });

@IBOutlet weak var artisttextfield: UITextField!
@IBOutlet weak var albumtextfield: UITextField!
@IBOutlet weak var releasedatePicker: UIDatePicker!

答案 3 :(得分:0)

只需修改@barmar方法。我已经使用Object.keys从对象获取密钥。这将删除所有硬编码的依赖项。

var response = {
  "data": {
    "data": [{
      "1": "Arun",
      "index": "name"
    }, {
      "1": 70.78,
      "index": "score"
    }]
  }
}

const mappedData = response.data.data.reduce((acc, item,i) => {
  
  var key = Object.keys(item);
  acc[item[key[1]]] =  item[key[0]]
  return acc ;
      
}, {});

console.log(mappedData)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>