如何将一个 JavaScript 数组映射到另一个 JavaScript 数组?

18

我在JavaScript中有一个构造函数,其中包含两个属性KeyValues数组

function Test(key, values) {
    this.Key = key;
    this.Values = values.map(values);
}

然后我创建了一个Test对象的数组:

 var testObjectArray = [];
 testObjectArray.push(new Test(1, ['a1','b1']), new Test(2, ['a1','b2']));

现在我想要将 testObjectArray 映射为单一的 key-value 数组,类似于:

现在我希望将 testObjectArray 映射为一个仅包含单个 键-值对 的数组,类似于:

[
    { "Key" : "1", "Value" : "a1" },
    { "Key" : "1", "Value" : "b1" },
    { "Key" : "2", "Value" : "a2" },
    { "Key" : "2", "Value" : "b2" },
]

我该如何使用数组的map函数实现这个呢?


在我看来,这似乎不是使用.map()的好案例。 - Pointy
我猜你的意思是 .push - keyser
5个回答

22

我想你可能误解了map()的用法。这里有一个非常简单的例子:

a = [1, 2, 3]
b = a.map(function (i) { return i + 1 })
// => [2, 3, 4]

这里是 map 的 MDN 文档:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map。所以你应该重新考虑在你的情况下使用 map。顺便说一句 - 你的例子无法运行,因为 values 不是一个函数。

以下是可能的解决方案:

res = [];
a = [['a1','b1'],['a1','b2']];

for (var i = 0; i < a.length; ++i) {
  for(var j = 0; j < a[i].length; ++j) {
    res.push({"Key": i + 1 , "Value" : a[i][j]});
  }
}

2
我确定还有其他方法,但这里有一个使用纯Javascript的方法可以实现你想要的功能: http://jsfiddle.net/KXBRw/
function Test(key, values) {
    this.Key = key;
    this.Values = values;//values.map(values);
}

function getCombinedTests(testObjectArray) {
    var all = [];
    for (var i = 0; i < testObjectArray.length; i++) {
        var cur = testObjectArray[i];
        for (var j = 0; j < cur.Values.length; j++) {
            all.push({"Key": ""+cur.Key, "Value": cur.Values[j]});
        }
    }
    return all;
}

var testObjectArray1 = [];
testObjectArray1.push(new Test(1, ['a1','b1']), new Test(2, ['a1','b2']));

var combined = getCombinedTests(testObjectArray1);

console.log(combined);

0
你可以使用 .reduce().concat().map() 来实现这个功能。
var result = testObjectArray.reduce(function(res, obj) {
    return res.concat(obj.Values.map(function(val) {
        return {"Key":obj.Key, "Value":val};
    }));
}, []);

不过我不确定 values.map(values); 的作用是什么。

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

[
    {
        "Key": 1,
        "Value": "a1"
    },
    {
        "Key": 1,
        "Value": "b1"
    },
    {
        "Key": 2,
        "Value": "a1"
    },
    {
        "Key": 2,
        "Value": "b2"
    }
]

如果您非常严格地不想创建不必要的数组,可以稍微调整一下,使用.push()而不是.concat()

var result = testObjectArray.reduce(function(res, obj) {
    res.push.apply(res, obj.Values.map(function(val) {
        return {"Key":obj.Key, "Value":val};
    }));
    return res;
}, []);

演示:http://jsfiddle.net/BWNGr/1/


0
您可以通过使用以下的for each循环来实现这一点,其中每个键值对将被推送到一个数组中。
var mapped = [];
$.each(testObjectArray, function(key, value) { 
  for(x in value.Values) {
    mapped.push({
      Key: value.Key,
      Value: x
    });
  }
});

1
请添加一些解释。 - ozil

0
所以,我正在学习编码,并试图了解更多关于map()的实现。我遇到了这个问题,这些答案让我想到了一种利用map()来实现OP最初想要的方式。这是最好的方法吗?我不知道,但从技术上讲,它与我认为OP的目标类似,并帮助我更好地理解了map()的工作原理。
let anArray = [{thingy: 'thing', num: 1, bool: true, color: 'blue', numTwo: 3}];
let newArray = anArray.map((item) => {
    return item;
});

console.log(newArray)会显示与anArray相同的内容。

如果我错了,请告诉我!


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