如何以不同的方式合并 javascript 中的数组?

How to merge arrays in javascript in a different way?

我想以稍微不同的方式合并数组。 我有 2 个或更多数组,例如:

var array1 = ["apple", "banana"];

var array2 = ["apple", "apple", "orange"];

我想要输出:

var array3 = ["apple", "apple", "banana", "orange"];

因此,如果任何给定数组中不止一次包含一个变量,合并算法应该将所有变量都从该数组中保留下来。

我看到了一些防止重复的代码,但它给出的输出如下:

var array3 = ["apple", "banana", "orange"];

更多示例:

var arr1 = [1,2,3,4];

var arr2 = [1,1,2,4,5,5,5];

var arr3 = [1,3,3,5,5];

我想要输出:

var array4 = [1,1,2,3,3,4,5,5,5];

我该怎么做?

未经测试且不是 JS,但我认为这就是您要找的。 我刚刚对其进行了手动测试,它适用于您的测试用例。

while items in lista or items in listb
    compare a.head, b.head
    if a.head is smaller or b.is_empty then 
         append a.head to output
         a.drophead
    else if b.head is smaller or a.is_empty then
         append b.head to output
         b.drophead
    else
         append b.head to output
         b.drophead
         a.drophead

这是一种计算每个数组中每个项目出现的次数的方法:

var arr1 = [1,2,3,4];
var arr2 = [1,1,2,4,5,5,5];
var arr3 = [1,3,3,5,5];

function joinCommon(/* list of arrays */) {
    var arr, arrayCounts, masterList = {}, item, output;
    // for each array passed in
    for (var i = 0; i < arguments.length; i++) {
        arr = arguments[i];
        arrayCounts = {};
        // iterate each array
        for (var j = 0; j < arr.length; j++) {
            item = arr[j];
            if (!arrayCounts[item]) {
                arrayCounts[item] = 1;
            } else {
                ++arrayCounts[item];
            }
            // now keep master list and master counts
            if (!masterList[item]) {
                masterList[item] = {cnt: 1, val: item};
            } else {
                masterList[item].cnt = Math.max(masterList[item].cnt, arrayCounts[item]);
            }
        }
    }
    // now output result
    output = [];
    for (var i in masterList) {
        for (var j = 0; j < masterList[i].cnt; j++) {
            output.push(masterList[i].val);
        }
    }
    return output;    
}

var results = joinCommon(arr1, arr2, arr3);

工作演示:http://jsfiddle.net/jfriend00/dtn6zw4m/

我喜欢用 ramda (http://ramdajs.com/docs/index.html) 来处理这些东西

var arr1 = [1,2,3,4];

var arr2 = [1,1,2,4,5,5,5];

var arr3 = [1,3,3,5,5];

var allArrays = [arr1, arr2, arr3];

var allValues = R.compose(R.uniq, R.flatten)(allArrays);

var getItemCounts = R.countBy(function(item) {
   return item;
});

var itemCounts = R.map(function(arr) {
   return getItemCounts(arr);
})(allArrays);

var combined = [];
R.forEach(function(item) {
   var countsForItem = R.pluck(item, itemCounts);
   var maxCount = R.max(countsForItem);
   combined.push.apply(combined, R.repeatN(item, maxCount));
})(allValues);

console.log(combined.sort());

JSFiddle:http://jsfiddle.net/pcr0q1xa/3/

这是一个使用 ECMA5 的解决方案。

Javascript

function indexOf(items, value) {
    return items.map(function (subitem) {
        return subitem.value;
    }).indexOf(value);
}

function countItems(previous, item) {
    var atIndex = indexOf(previous, item);

    if (atIndex !== -1) {
        previous[atIndex].count += 1;
    } else {
        previous.push({
            value: item,
            count: 1
        });
    }

    return previous;
}

function mergeCounts(item) {
    var atIndex = indexOf(this, item.value);

    if (atIndex === -1) {
        this.push(item);
    } else if (this[atIndex].count < item.count) {
        this[atIndex] = item;
    }
}

function expandCounts(previous, item) {
    var iter;

    for (iter = 0; iter < item.count; iter += 1) {
        previous.push(item.value);
    }

    return previous;
}

function mergeArg(items, arg) {
    arg.reduce(countItems, []).forEach(mergeCounts, items);

    return items;
}

function mergeMaxItems() {
    return [].reduce.call(arguments, mergeArg, []).reduce(expandCounts, []);
}

var arr1 = [1, 2, 3, 4],
    arr2 = [1, 1, 2, 4, 5, 5, 5],
    arr3 = [1, 3, 3, 5, 5];

document.body.appendChild(document.createTextNode(mergeMaxItems(arr1, arr2, arr3)));

Ramda是你的朋友。

function merge () {
  return R.chain(R.apply(R.repeat), R.toPairs(R.reduce(
    R.mergeWith(R.max),
    {},
    R.map(R.countBy(R.identity), arguments)
  )))
}

var array1 = ["apple", "banana"];

var array2 = ["apple", "apple", "orange"];

console.log(JSON.stringify(merge(array1, array2)))

var arr1 = [1,2,3,4];

var arr2 = [1,1,2,4,5,5,5];

var arr3 = [1,3,3,5,5];

console.log(JSON.stringify(merge(arr1, arr2, arr3)))
<script src="http://cdnjs.cloudflare.com/ajax/libs/ramda/0.22.1/ramda.min.js"></script>