【问题标题】:how to move elements in nested array of objects in javascript如何在javascript中移动嵌套对象数组中的元素
【发布时间】:2022-01-04 13:29:34
【问题描述】:

我看到了这两个问题:

  1. Javascript move objects in a nested array
  2. How to move element in nested array

但它们对我不起作用。

所以我有一个这样的嵌套动态数组:

const data = [
  {
    id: 1,
    subData: [
      {
        id: 2,
        subData: []
      },
      {
        id: 3,
        subData: [
          {
            id: 4,
            subData: []
          }
        ]
      }
    ]
  },
  {
    id: 5,
    subData: []
  },
  .
  .
  .
]

我必须用它们的"id" 移动嵌套元素。例如,我怎样才能编写一个函数来给我以下结果:

const data = [
  {
    id: 1,
    subData: [
      {
        id: 2,
        subData: []
      },
      {
        id: 3,
        subData: [] // object with id 4 was here
      }
    ]
  },
  {
    id: 5,
    subData: []
  },
  {
    id: 4, // now its here
    subData: []
  }
  .
  .
  .
]

到目前为止,我尝试编写以下函数来首先找到具有特定 "id" 的元素,然后移动该对象:

const findObjById = (obj, key, value) => {
  if (obj[key] === value) {
    return obj;
  }

  const keys = Object.keys(obj);
  for (let i = 0; i < keys.length; i++) {
    const k = keys[i];

    if (obj[k] && typeof obj[k] === 'object') {
      const found = findObjById(obj[k], key, value);

      if (found) {
        return found;
      }
    }
  }
}

用于查找特定对象。但我无法移动找到的对象

【问题讨论】:

  • 而不是仅仅返回对象,你应该splice()它离开它所在的数组,然后找到你想要移动它的数组和push()它。
  • @pilchard 这正是我想到的方法。但我真的做不到。你能用你的方法重写那个函数吗?

标签: javascript arrays object


【解决方案1】:

这是一个使用通用traverse 函数的示例,该函数接受visitor 回调,该回调在遍历的每次迭代中运行,并根据访问者的返回值返回或继续。 (更多讨论请参见answer)。

然后我们可以创建一个splice_source 遍历,它接受一个要遍历的对象和一个要匹配的谓词,并在从其父数组拼接后返回匹配的元素,以及一个find_target_array,它将返回subData 数组来自与传递的谓词匹配的对象。

只剩下将检索到的源对象推送到检索到的目标数组。

这只是一个示例,需要针对您的特定用例进行错误检查和简化,但它说明了一些灵活的技术,这些技术可能对未来有用。

const data = [{ id: 1, subData: [{ id: 2, subData: [], }, { id: 3, subData: [{ id: 4, subData: [], },], },], }, { id: 5, subData: [], },];

// generic 'traverse' which accepts a 'visitor' callback
function traverse(o, fn) {
  for (const k in o) {
    const res = fn.apply(this, [o, k]);
    if (res) {
      return res;
    }
    if (o[k] !== null && typeof o[k] == 'object') {
      const res = traverse(o[k], fn);
      if (res) return res;
    }
  }
}

// create custom 'visitors' to retrieve source and target arrays
const splice_source = (obj, predicate) =>
  traverse(
    obj,
    // 'visitor' callback
    (o, k) => {
      let m_index = -1;
      if (Array.isArray(o[k])) {
        m_index = o[k].findIndex((o) => predicate(o, k));
      }

      return m_index !== -1 ? o[k].splice(m_index, 1)[0] : false;
    });

const find_target_array = (obj, predicate) => 
  traverse(
    obj,
    // 'visitor' callback
    (o, k) => (predicate(o, k) ? o.subData : false)
  );

// move {id: 4} to subData array of {id: 5}
const source_object = splice_source(data, (obj) => obj?.id === 4);
const target_array = find_target_array(data, (obj) => obj?.id === 5);

target_array.push(source_object);
console.log(JSON.stringify(data, null, 2));

// move {id: 3} to top level 'data' array
data.push(splice_source(data, (obj) => obj?.id === 3));
console.log(JSON.stringify(data, null, 2));
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-21
    • 1970-01-01
    • 2020-11-22
    • 1970-01-01
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多